From 4af75df6a410ce76d9f60f27b07e5645ecc2c5ed Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 25 Feb 2016 08:32:51 -0800 Subject: binfmt_misc: add F option description to documentation Signed-off-by: James Bottomley --- Documentation/binfmt_misc.txt | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Documentation') diff --git a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt index 6b1de7058371..ec83bbce547a 100644 --- a/Documentation/binfmt_misc.txt +++ b/Documentation/binfmt_misc.txt @@ -66,6 +66,13 @@ Here is what the fields mean: This feature should be used with care as the interpreter will run with root permissions when a setuid binary owned by root is run with binfmt_misc. + 'F' - fix binary. The usual behaviour of binfmt_misc is to spawn the + binary lazily when the misc format file is invoked. However, + this doesn't work very well in the face of mount namespaces and + changeroots, so the F mode opens the binary as soon as the + emulation is installed and uses the opened image to spawn the + emulator, meaning it is always available once installed, + regardless of how the environment changes. There are some restrictions: -- cgit v1.3-14-g43fede From 81f517270da632c0ddf4c511a086d5aa7e5606ee Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Sun, 1 May 2016 15:36:54 -0500 Subject: iio: health/afe440x: Always use separate gain values Locking the two gain stages to the same setting adds no value for us, so initialize them as unlocked and remove the sysfs for unlocking them. This also allows us to greatly simplify showing and setting the gain registers. Signed-off-by: Andrew F. Davis Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-health-afe440x | 9 ---- drivers/iio/health/afe4403.c | 60 ++++++---------------- drivers/iio/health/afe4404.c | 60 ++++++---------------- drivers/iio/health/afe440x.h | 15 ++---- 4 files changed, 37 insertions(+), 107 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x index 3740f253d406..b19053a86054 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x +++ b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x @@ -8,15 +8,6 @@ Description: Transimpedance Amplifier. Y is 1 for Rf1 and Cf1, Y is 2 for Rf2 and Cf2 values. -What: /sys/bus/iio/devices/iio:deviceX/tia_separate_en -Date: December 2015 -KernelVersion: -Contact: Andrew F. Davis -Description: - Enable or disable separate settings for the TransImpedance - Amplifier above, when disabled both values are set by the - first channel. - What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_raw /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_ambient_raw Date: December 2015 diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index 54847853eb7a..bcff5280c5c9 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -180,9 +180,9 @@ static ssize_t afe440x_show_register(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct afe4403_data *afe = iio_priv(indio_dev); struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr); - unsigned int reg_val, type; + unsigned int reg_val; int vals[2]; - int ret, val_len; + int ret; ret = regmap_read(afe->regmap, afe440x_attr->reg, ®_val); if (ret) @@ -191,27 +191,13 @@ static ssize_t afe440x_show_register(struct device *dev, reg_val &= afe440x_attr->mask; reg_val >>= afe440x_attr->shift; - switch (afe440x_attr->type) { - case SIMPLE: - type = IIO_VAL_INT; - val_len = 1; - vals[0] = reg_val; - break; - case RESISTANCE: - case CAPACITANCE: - type = IIO_VAL_INT_PLUS_MICRO; - val_len = 2; - if (reg_val < afe440x_attr->table_size) { - vals[0] = afe440x_attr->val_table[reg_val].integer; - vals[1] = afe440x_attr->val_table[reg_val].fract; - break; - } + if (reg_val >= afe440x_attr->table_size) return -EINVAL; - default: - return -EINVAL; - } - return iio_format_value(buf, type, val_len, vals); + vals[0] = afe440x_attr->val_table[reg_val].integer; + vals[1] = afe440x_attr->val_table[reg_val].fract; + + return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals); } static ssize_t afe440x_store_register(struct device *dev, @@ -227,22 +213,12 @@ static ssize_t afe440x_store_register(struct device *dev, if (ret) return ret; - switch (afe440x_attr->type) { - case SIMPLE: - val = integer; - break; - case RESISTANCE: - case CAPACITANCE: - for (val = 0; val < afe440x_attr->table_size; val++) - if (afe440x_attr->val_table[val].integer == integer && - afe440x_attr->val_table[val].fract == fract) - break; - if (val == afe440x_attr->table_size) - return -EINVAL; - break; - default: + for (val = 0; val < afe440x_attr->table_size; val++) + if (afe440x_attr->val_table[val].integer == integer && + afe440x_attr->val_table[val].fract == fract) + break; + if (val == afe440x_attr->table_size) return -EINVAL; - } ret = regmap_update_bits(afe->regmap, afe440x_attr->reg, afe440x_attr->mask, @@ -253,16 +229,13 @@ static ssize_t afe440x_store_register(struct device *dev, return count; } -static AFE440X_ATTR(tia_separate_en, AFE4403_TIAGAIN, AFE440X_TIAGAIN_ENSEPGAIN, SIMPLE, NULL, 0); - -static AFE440X_ATTR(tia_resistance1, AFE4403_TIAGAIN, AFE4403_TIAGAIN_RES, RESISTANCE, afe4403_res_table, ARRAY_SIZE(afe4403_res_table)); -static AFE440X_ATTR(tia_capacitance1, AFE4403_TIAGAIN, AFE4403_TIAGAIN_CAP, CAPACITANCE, afe4403_cap_table, ARRAY_SIZE(afe4403_cap_table)); +static AFE440X_ATTR(tia_resistance1, AFE4403_TIAGAIN, AFE4403_TIAGAIN_RES, afe4403_res_table); +static AFE440X_ATTR(tia_capacitance1, AFE4403_TIAGAIN, AFE4403_TIAGAIN_CAP, afe4403_cap_table); -static AFE440X_ATTR(tia_resistance2, AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES, RESISTANCE, afe4403_res_table, ARRAY_SIZE(afe4403_res_table)); -static AFE440X_ATTR(tia_capacitance2, AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES, CAPACITANCE, afe4403_cap_table, ARRAY_SIZE(afe4403_cap_table)); +static AFE440X_ATTR(tia_resistance2, AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES, afe4403_res_table); +static AFE440X_ATTR(tia_capacitance2, AFE4403_TIA_AMB_GAIN, AFE4403_TIAGAIN_RES, afe4403_cap_table); static struct attribute *afe440x_attributes[] = { - &afe440x_attr_tia_separate_en.dev_attr.attr, &afe440x_attr_tia_resistance1.dev_attr.attr, &afe440x_attr_tia_capacitance1.dev_attr.attr, &afe440x_attr_tia_resistance2.dev_attr.attr, @@ -473,6 +446,7 @@ static const struct iio_trigger_ops afe4403_trigger_ops = { static const struct reg_sequence afe4403_reg_sequences[] = { AFE4403_TIMING_PAIRS, { AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN }, + { AFE4403_TIAGAIN, AFE440X_TIAGAIN_ENSEPGAIN }, }; static const struct regmap_range afe4403_yes_ranges[] = { diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 2d4c522f81e1..b9c1666c963b 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -193,9 +193,9 @@ static ssize_t afe440x_show_register(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct afe4404_data *afe = iio_priv(indio_dev); struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr); - unsigned int reg_val, type; + unsigned int reg_val; int vals[2]; - int ret, val_len; + int ret; ret = regmap_read(afe->regmap, afe440x_attr->reg, ®_val); if (ret) @@ -204,27 +204,13 @@ static ssize_t afe440x_show_register(struct device *dev, reg_val &= afe440x_attr->mask; reg_val >>= afe440x_attr->shift; - switch (afe440x_attr->type) { - case SIMPLE: - type = IIO_VAL_INT; - val_len = 1; - vals[0] = reg_val; - break; - case RESISTANCE: - case CAPACITANCE: - type = IIO_VAL_INT_PLUS_MICRO; - val_len = 2; - if (reg_val < afe440x_attr->table_size) { - vals[0] = afe440x_attr->val_table[reg_val].integer; - vals[1] = afe440x_attr->val_table[reg_val].fract; - break; - } + if (reg_val >= afe440x_attr->table_size) return -EINVAL; - default: - return -EINVAL; - } - return iio_format_value(buf, type, val_len, vals); + vals[0] = afe440x_attr->val_table[reg_val].integer; + vals[1] = afe440x_attr->val_table[reg_val].fract; + + return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals); } static ssize_t afe440x_store_register(struct device *dev, @@ -240,22 +226,12 @@ static ssize_t afe440x_store_register(struct device *dev, if (ret) return ret; - switch (afe440x_attr->type) { - case SIMPLE: - val = integer; - break; - case RESISTANCE: - case CAPACITANCE: - for (val = 0; val < afe440x_attr->table_size; val++) - if (afe440x_attr->val_table[val].integer == integer && - afe440x_attr->val_table[val].fract == fract) - break; - if (val == afe440x_attr->table_size) - return -EINVAL; - break; - default: + for (val = 0; val < afe440x_attr->table_size; val++) + if (afe440x_attr->val_table[val].integer == integer && + afe440x_attr->val_table[val].fract == fract) + break; + if (val == afe440x_attr->table_size) return -EINVAL; - } ret = regmap_update_bits(afe->regmap, afe440x_attr->reg, afe440x_attr->mask, @@ -266,16 +242,13 @@ static ssize_t afe440x_store_register(struct device *dev, return count; } -static AFE440X_ATTR(tia_separate_en, AFE4404_TIA_GAIN_SEP, AFE440X_TIAGAIN_ENSEPGAIN, SIMPLE, NULL, 0); - -static AFE440X_ATTR(tia_resistance1, AFE4404_TIA_GAIN, AFE4404_TIA_GAIN_RES, RESISTANCE, afe4404_res_table, ARRAY_SIZE(afe4404_res_table)); -static AFE440X_ATTR(tia_capacitance1, AFE4404_TIA_GAIN, AFE4404_TIA_GAIN_CAP, CAPACITANCE, afe4404_cap_table, ARRAY_SIZE(afe4404_cap_table)); +static AFE440X_ATTR(tia_resistance1, AFE4404_TIA_GAIN, AFE4404_TIA_GAIN_RES, afe4404_res_table); +static AFE440X_ATTR(tia_capacitance1, AFE4404_TIA_GAIN, AFE4404_TIA_GAIN_CAP, afe4404_cap_table); -static AFE440X_ATTR(tia_resistance2, AFE4404_TIA_GAIN_SEP, AFE4404_TIA_GAIN_RES, RESISTANCE, afe4404_res_table, ARRAY_SIZE(afe4404_res_table)); -static AFE440X_ATTR(tia_capacitance2, AFE4404_TIA_GAIN_SEP, AFE4404_TIA_GAIN_CAP, CAPACITANCE, afe4404_cap_table, ARRAY_SIZE(afe4404_cap_table)); +static AFE440X_ATTR(tia_resistance2, AFE4404_TIA_GAIN_SEP, AFE4404_TIA_GAIN_RES, afe4404_res_table); +static AFE440X_ATTR(tia_capacitance2, AFE4404_TIA_GAIN_SEP, AFE4404_TIA_GAIN_CAP, afe4404_cap_table); static struct attribute *afe440x_attributes[] = { - &afe440x_attr_tia_separate_en.dev_attr.attr, &afe440x_attr_tia_resistance1.dev_attr.attr, &afe440x_attr_tia_capacitance1.dev_attr.attr, &afe440x_attr_tia_resistance2.dev_attr.attr, @@ -443,6 +416,7 @@ static const struct iio_trigger_ops afe4404_trigger_ops = { static const struct reg_sequence afe4404_reg_sequences[] = { AFE4404_TIMING_PAIRS, { AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN }, + { AFE4404_TIA_GAIN_SEP, AFE440X_TIAGAIN_ENSEPGAIN }, { AFE440X_CONTROL2, AFE440X_CONTROL3_OSC_ENABLE }, }; diff --git a/drivers/iio/health/afe440x.h b/drivers/iio/health/afe440x.h index c671ab78a23a..544bbabd6321 100644 --- a/drivers/iio/health/afe440x.h +++ b/drivers/iio/health/afe440x.h @@ -71,8 +71,7 @@ #define AFE440X_CONTROL1_TIMEREN BIT(8) /* TIAGAIN register fields */ -#define AFE440X_TIAGAIN_ENSEPGAIN_MASK BIT(15) -#define AFE440X_TIAGAIN_ENSEPGAIN_SHIFT 15 +#define AFE440X_TIAGAIN_ENSEPGAIN BIT(15) /* CONTROL2 register fields */ #define AFE440X_CONTROL2_PDN_AFE BIT(0) @@ -133,12 +132,6 @@ struct afe440x_reg_info { .output = true, \ } -enum afe440x_reg_type { - SIMPLE, - RESISTANCE, - CAPACITANCE, -}; - struct afe440x_val_table { int integer; int fract; @@ -167,7 +160,6 @@ struct afe440x_attr { unsigned int reg; unsigned int shift; unsigned int mask; - enum afe440x_reg_type type; const struct afe440x_val_table *val_table; unsigned int table_size; }; @@ -175,7 +167,7 @@ struct afe440x_attr { #define to_afe440x_attr(_dev_attr) \ container_of(_dev_attr, struct afe440x_attr, dev_attr) -#define AFE440X_ATTR(_name, _reg, _field, _type, _table, _size) \ +#define AFE440X_ATTR(_name, _reg, _field, _table) \ struct afe440x_attr afe440x_attr_##_name = { \ .dev_attr = __ATTR(_name, (S_IRUGO | S_IWUSR), \ afe440x_show_register, \ @@ -183,9 +175,8 @@ struct afe440x_attr { .reg = _reg, \ .shift = _field ## _SHIFT, \ .mask = _field ## _MASK, \ - .type = _type, \ .val_table = _table, \ - .table_size = _size, \ + .table_size = ARRAY_SIZE(_table), \ } #endif /* _AFE440X_H */ -- cgit v1.3-14-g43fede From 24b9dea764bdf0de8434fb4567e7f62038ba869e Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Sun, 1 May 2016 15:36:58 -0500 Subject: iio: health/afe440x: Remove channel names These AFEs have 4 ADC mesuring stages (called LED2, ALED2, LED1, and ALED1 in the datasheet), we map these as channels, these stages can serve different purposes depending on the application. For instance the AFE4404 has an additional LED (LED3), this LED can be timed to be active during stage 2 (or anystage, but the datasheet describes this case and the name of the stage reflects this use). This ability is used further in upcoming parts that tie the front-end gain and the LED timings together. For these reasons we remove explicit naming the channels. Without channel names it is best that the index numbers are in order to match the stage number, reorder the channel numbers. Signed-off-by: Andrew F. Davis Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-health-afe440x | 39 ++++++++++------------ drivers/iio/health/afe4403.c | 28 ++++++++-------- drivers/iio/health/afe4404.c | 30 ++++++++--------- drivers/iio/health/afe440x.h | 8 ++--- 4 files changed, 51 insertions(+), 54 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x index b19053a86054..a06707320d84 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x +++ b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x @@ -8,38 +8,35 @@ Description: Transimpedance Amplifier. Y is 1 for Rf1 and Cf1, Y is 2 for Rf2 and Cf2 values. -What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_raw - /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_ambient_raw -Date: December 2015 +What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_raw +Date: May 2016 KernelVersion: Contact: Andrew F. Davis Description: Get measured values from the ADC for these stages. Y is the - specific LED number. The values are expressed in 24-bit twos - complement. - -What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY-ledY_ambient_raw -Date: December 2015 -KernelVersion: -Contact: Andrew F. Davis -Description: - Get differential values from the ADC for these stages. Y is the - specific LED number. The values are expressed in 24-bit twos - complement for the specified LEDs. + specific stage number corresponding to datasheet stage names + as follows: + 1 -> LED2 + 2 -> ALED2/LED3 + 3 -> LED1 + 4 -> ALED1/LED4 + Note that channels 5 and 6 represent LED2-ALED2 and LED1-ALED1 + respectively which simply helper channels containing the + calculated difference in the value of stage 1 - 2 and 3 - 4. + The values are expressed in 24-bit twos complement. -What: /sys/bus/iio/devices/iio:deviceX/out_current_ledY_offset - /sys/bus/iio/devices/iio:deviceX/out_current_ledY_ambient_offset -Date: December 2015 +What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_offset +Date: May 2016 KernelVersion: Contact: Andrew F. Davis Description: Get and set the offset cancellation DAC setting for these stages. The values are expressed in 5-bit sign-magnitude. -What: /sys/bus/iio/devices/iio:deviceX/out_current_ledY_raw -Date: December 2015 +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw +Date: May 2016 KernelVersion: Contact: Andrew F. Davis Description: - Get and set the LED current for the specified LED. Y is the - specific LED number. + Get and set the LED current for the specified LED active during + this stage. Y is the specific stage number. diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index cac60909a585..4a580646f10e 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -121,38 +121,38 @@ struct afe4403_data { }; enum afe4403_chan_id { + LED2 = 1, + ALED2, LED1, ALED1, - LED2, - ALED2, - LED1_ALED1, LED2_ALED2, + LED1_ALED1, ILED1, ILED2, }; static const struct afe440x_reg_info afe4403_reg_info[] = { - [LED1] = AFE440X_REG_INFO(AFE440X_LED1VAL, 0, NULL), - [ALED1] = AFE440X_REG_INFO(AFE440X_ALED1VAL, 0, NULL), [LED2] = AFE440X_REG_INFO(AFE440X_LED2VAL, 0, NULL), [ALED2] = AFE440X_REG_INFO(AFE440X_ALED2VAL, 0, NULL), - [LED1_ALED1] = AFE440X_REG_INFO(AFE440X_LED1_ALED1VAL, 0, NULL), + [LED1] = AFE440X_REG_INFO(AFE440X_LED1VAL, 0, NULL), + [ALED1] = AFE440X_REG_INFO(AFE440X_ALED1VAL, 0, NULL), [LED2_ALED2] = AFE440X_REG_INFO(AFE440X_LED2_ALED2VAL, 0, NULL), + [LED1_ALED1] = AFE440X_REG_INFO(AFE440X_LED1_ALED1VAL, 0, NULL), [ILED1] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE440X_LEDCNTRL_LED1), [ILED2] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE440X_LEDCNTRL_LED2), }; static const struct iio_chan_spec afe4403_channels[] = { /* ADC values */ - AFE440X_INTENSITY_CHAN(LED1, "led1", 0), - AFE440X_INTENSITY_CHAN(ALED1, "led1_ambient", 0), - AFE440X_INTENSITY_CHAN(LED2, "led2", 0), - AFE440X_INTENSITY_CHAN(ALED2, "led2_ambient", 0), - AFE440X_INTENSITY_CHAN(LED1_ALED1, "led1-led1_ambient", 0), - AFE440X_INTENSITY_CHAN(LED2_ALED2, "led2-led2_ambient", 0), + AFE440X_INTENSITY_CHAN(LED2, 0), + AFE440X_INTENSITY_CHAN(ALED2, 0), + AFE440X_INTENSITY_CHAN(LED1, 0), + AFE440X_INTENSITY_CHAN(ALED1, 0), + AFE440X_INTENSITY_CHAN(LED2_ALED2, 0), + AFE440X_INTENSITY_CHAN(LED1_ALED1, 0), /* LED current */ - AFE440X_CURRENT_CHAN(ILED1, "led1"), - AFE440X_CURRENT_CHAN(ILED2, "led2"), + AFE440X_CURRENT_CHAN(ILED1), + AFE440X_CURRENT_CHAN(ILED2), }; static const struct afe440x_val_table afe4403_res_table[] = { diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 2edb7d75ef38..7806a452edf8 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -122,24 +122,24 @@ struct afe4404_data { }; enum afe4404_chan_id { + LED2 = 1, + ALED2, LED1, ALED1, - LED2, - ALED2, - LED1_ALED1, LED2_ALED2, + LED1_ALED1, ILED1, ILED2, ILED3, }; static const struct afe440x_reg_info afe4404_reg_info[] = { - [LED1] = AFE440X_REG_INFO(AFE440X_LED1VAL, AFE4404_OFFDAC, AFE4404_OFFDAC_CURR_LED1), - [ALED1] = AFE440X_REG_INFO(AFE440X_ALED1VAL, AFE4404_OFFDAC, AFE4404_OFFDAC_CURR_ALED1), [LED2] = AFE440X_REG_INFO(AFE440X_LED2VAL, AFE4404_OFFDAC, AFE4404_OFFDAC_CURR_LED2), [ALED2] = AFE440X_REG_INFO(AFE440X_ALED2VAL, AFE4404_OFFDAC, AFE4404_OFFDAC_CURR_ALED2), - [LED1_ALED1] = AFE440X_REG_INFO(AFE440X_LED1_ALED1VAL, 0, NULL), + [LED1] = AFE440X_REG_INFO(AFE440X_LED1VAL, AFE4404_OFFDAC, AFE4404_OFFDAC_CURR_LED1), + [ALED1] = AFE440X_REG_INFO(AFE440X_ALED1VAL, AFE4404_OFFDAC, AFE4404_OFFDAC_CURR_ALED1), [LED2_ALED2] = AFE440X_REG_INFO(AFE440X_LED2_ALED2VAL, 0, NULL), + [LED1_ALED1] = AFE440X_REG_INFO(AFE440X_LED1_ALED1VAL, 0, NULL), [ILED1] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE4404_LEDCNTRL_ILED1), [ILED2] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE4404_LEDCNTRL_ILED2), [ILED3] = AFE440X_REG_INFO(AFE440X_LEDCNTRL, 0, AFE4404_LEDCNTRL_ILED3), @@ -147,16 +147,16 @@ static const struct afe440x_reg_info afe4404_reg_info[] = { static const struct iio_chan_spec afe4404_channels[] = { /* ADC values */ - AFE440X_INTENSITY_CHAN(LED1, "led1", BIT(IIO_CHAN_INFO_OFFSET)), - AFE440X_INTENSITY_CHAN(ALED1, "led1_ambient", BIT(IIO_CHAN_INFO_OFFSET)), - AFE440X_INTENSITY_CHAN(LED2, "led2", BIT(IIO_CHAN_INFO_OFFSET)), - AFE440X_INTENSITY_CHAN(ALED2, "led2_ambient", BIT(IIO_CHAN_INFO_OFFSET)), - AFE440X_INTENSITY_CHAN(LED1_ALED1, "led1-led1_ambient", 0), - AFE440X_INTENSITY_CHAN(LED2_ALED2, "led2-led2_ambient", 0), + AFE440X_INTENSITY_CHAN(LED2, BIT(IIO_CHAN_INFO_OFFSET)), + AFE440X_INTENSITY_CHAN(ALED2, BIT(IIO_CHAN_INFO_OFFSET)), + AFE440X_INTENSITY_CHAN(LED1, BIT(IIO_CHAN_INFO_OFFSET)), + AFE440X_INTENSITY_CHAN(ALED1, BIT(IIO_CHAN_INFO_OFFSET)), + AFE440X_INTENSITY_CHAN(LED2_ALED2, 0), + AFE440X_INTENSITY_CHAN(LED1_ALED1, 0), /* LED current */ - AFE440X_CURRENT_CHAN(ILED1, "led1"), - AFE440X_CURRENT_CHAN(ILED2, "led2"), - AFE440X_CURRENT_CHAN(ILED3, "led3"), + AFE440X_CURRENT_CHAN(ILED1), + AFE440X_CURRENT_CHAN(ILED2), + AFE440X_CURRENT_CHAN(ILED3), }; static const struct afe440x_val_table afe4404_res_table[] = { diff --git a/drivers/iio/health/afe440x.h b/drivers/iio/health/afe440x.h index 583d071af11d..713972fd4601 100644 --- a/drivers/iio/health/afe440x.h +++ b/drivers/iio/health/afe440x.h @@ -103,7 +103,7 @@ struct afe440x_reg_info { .mask = _sm ## _MASK, \ } -#define AFE440X_INTENSITY_CHAN(_index, _name, _mask) \ +#define AFE440X_INTENSITY_CHAN(_index, _mask) \ { \ .type = IIO_INTENSITY, \ .channel = _index, \ @@ -115,20 +115,20 @@ struct afe440x_reg_info { .storagebits = 32, \ .endianness = IIO_CPU, \ }, \ - .extend_name = _name, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ _mask, \ + .indexed = true, \ } -#define AFE440X_CURRENT_CHAN(_index, _name) \ +#define AFE440X_CURRENT_CHAN(_index) \ { \ .type = IIO_CURRENT, \ .channel = _index, \ .address = _index, \ .scan_index = -1, \ - .extend_name = _name, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ + .indexed = true, \ .output = true, \ } -- cgit v1.3-14-g43fede From 1276187c5261217aa9cc23ec153e0e903181c16b Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Sun, 1 May 2016 15:37:00 -0500 Subject: iio: health/afe440x: Make gain settings a modifier for the stages Currently the TIA gain settings are exported to userspace as sysfs entries that do not clearly represent their internal relation to the sampling stages. The gain settings are enabled on a per-stage basis, this can be seen in figure 24 of the current AFE4404 datasheet. These gain settings should therefore be tied to the channels that are read during these stages. Make this change here. Signed-off-by: Andrew F. Davis Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-health-afe440x | 19 ++++++------ drivers/iio/health/afe4403.c | 34 ++++++++++++++-------- drivers/iio/health/afe4404.c | 34 ++++++++++++++-------- 3 files changed, 53 insertions(+), 34 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x index a06707320d84..6adba9058b22 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x +++ b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x @@ -1,13 +1,3 @@ -What: /sys/bus/iio/devices/iio:deviceX/tia_resistanceY - /sys/bus/iio/devices/iio:deviceX/tia_capacitanceY -Date: December 2015 -KernelVersion: -Contact: Andrew F. Davis -Description: - Get and set the resistance and the capacitance settings for the - Transimpedance Amplifier. Y is 1 for Rf1 and Cf1, Y is 2 for - Rf2 and Cf2 values. - What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_raw Date: May 2016 KernelVersion: @@ -33,6 +23,15 @@ Description: Get and set the offset cancellation DAC setting for these stages. The values are expressed in 5-bit sign-magnitude. +What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_resistance +What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_capacitance +Date: May 2016 +KernelVersion: +Contact: Andrew F. Davis +Description: + Get and set the resistance and the capacitance settings for the + Transimpedance Amplifier during the associated stage. + What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw Date: May 2016 KernelVersion: diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index 19501550c6ff..610631b036ec 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -161,7 +161,7 @@ static const struct afe440x_val_table afe4403_res_table[] = { { 500000 }, { 250000 }, { 100000 }, { 50000 }, { 25000 }, { 10000 }, { 1000000 }, { 0 }, }; -AFE440X_TABLE_ATTR(tia_resistance_available, afe4403_res_table); +AFE440X_TABLE_ATTR(in_intensity_resistance_available, afe4403_res_table); static const struct afe440x_val_table afe4403_cap_table[] = { { 0, 5000 }, { 0, 10000 }, { 0, 20000 }, { 0, 25000 }, @@ -173,7 +173,7 @@ static const struct afe440x_val_table afe4403_cap_table[] = { { 0, 205000 }, { 0, 210000 }, { 0, 220000 }, { 0, 225000 }, { 0, 230000 }, { 0, 235000 }, { 0, 245000 }, { 0, 250000 }, }; -AFE440X_TABLE_ATTR(tia_capacitance_available, afe4403_cap_table); +AFE440X_TABLE_ATTR(in_intensity_capacitance_available, afe4403_cap_table); static ssize_t afe440x_show_register(struct device *dev, struct device_attribute *attr, @@ -226,19 +226,29 @@ static ssize_t afe440x_store_register(struct device *dev, return count; } -static AFE440X_ATTR(tia_resistance1, F_RF_LED1, afe4403_res_table); -static AFE440X_ATTR(tia_capacitance1, F_CF_LED1, afe4403_cap_table); +static AFE440X_ATTR(in_intensity1_resistance, F_RF_LED, afe4403_res_table); +static AFE440X_ATTR(in_intensity1_capacitance, F_CF_LED, afe4403_cap_table); -static AFE440X_ATTR(tia_resistance2, F_RF_LED, afe4403_res_table); -static AFE440X_ATTR(tia_capacitance2, F_CF_LED, afe4403_cap_table); +static AFE440X_ATTR(in_intensity2_resistance, F_RF_LED, afe4403_res_table); +static AFE440X_ATTR(in_intensity2_capacitance, F_CF_LED, afe4403_cap_table); + +static AFE440X_ATTR(in_intensity3_resistance, F_RF_LED1, afe4403_res_table); +static AFE440X_ATTR(in_intensity3_capacitance, F_CF_LED1, afe4403_cap_table); + +static AFE440X_ATTR(in_intensity4_resistance, F_RF_LED1, afe4403_res_table); +static AFE440X_ATTR(in_intensity4_capacitance, F_CF_LED1, afe4403_cap_table); static struct attribute *afe440x_attributes[] = { - &afe440x_attr_tia_resistance1.dev_attr.attr, - &afe440x_attr_tia_capacitance1.dev_attr.attr, - &afe440x_attr_tia_resistance2.dev_attr.attr, - &afe440x_attr_tia_capacitance2.dev_attr.attr, - &dev_attr_tia_resistance_available.attr, - &dev_attr_tia_capacitance_available.attr, + &dev_attr_in_intensity_resistance_available.attr, + &dev_attr_in_intensity_capacitance_available.attr, + &afe440x_attr_in_intensity1_resistance.dev_attr.attr, + &afe440x_attr_in_intensity1_capacitance.dev_attr.attr, + &afe440x_attr_in_intensity2_resistance.dev_attr.attr, + &afe440x_attr_in_intensity2_capacitance.dev_attr.attr, + &afe440x_attr_in_intensity3_resistance.dev_attr.attr, + &afe440x_attr_in_intensity3_capacitance.dev_attr.attr, + &afe440x_attr_in_intensity4_resistance.dev_attr.attr, + &afe440x_attr_in_intensity4_capacitance.dev_attr.attr, NULL }; diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 0d1af4a4a903..69116cdd9d92 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -179,7 +179,7 @@ static const struct afe440x_val_table afe4404_res_table[] = { { .integer = 1000000, .fract = 0 }, { .integer = 2000000, .fract = 0 }, }; -AFE440X_TABLE_ATTR(tia_resistance_available, afe4404_res_table); +AFE440X_TABLE_ATTR(in_intensity_resistance_available, afe4404_res_table); static const struct afe440x_val_table afe4404_cap_table[] = { { .integer = 0, .fract = 5000 }, @@ -191,7 +191,7 @@ static const struct afe440x_val_table afe4404_cap_table[] = { { .integer = 0, .fract = 25000 }, { .integer = 0, .fract = 22500 }, }; -AFE440X_TABLE_ATTR(tia_capacitance_available, afe4404_cap_table); +AFE440X_TABLE_ATTR(in_intensity_capacitance_available, afe4404_cap_table); static ssize_t afe440x_show_register(struct device *dev, struct device_attribute *attr, @@ -244,19 +244,29 @@ static ssize_t afe440x_store_register(struct device *dev, return count; } -static AFE440X_ATTR(tia_resistance1, F_TIA_GAIN, afe4404_res_table); -static AFE440X_ATTR(tia_capacitance1, TIA_CF, afe4404_cap_table); +static AFE440X_ATTR(in_intensity1_resistance, F_TIA_GAIN_SEP, afe4404_res_table); +static AFE440X_ATTR(in_intensity1_capacitance, F_TIA_CF_SEP, afe4404_cap_table); -static AFE440X_ATTR(tia_resistance2, F_TIA_GAIN_SEP, afe4404_res_table); -static AFE440X_ATTR(tia_capacitance2, F_TIA_CF_SEP, afe4404_cap_table); +static AFE440X_ATTR(in_intensity2_resistance, F_TIA_GAIN_SEP, afe4404_res_table); +static AFE440X_ATTR(in_intensity2_capacitance, F_TIA_CF_SEP, afe4404_cap_table); + +static AFE440X_ATTR(in_intensity3_resistance, F_TIA_GAIN, afe4404_res_table); +static AFE440X_ATTR(in_intensity3_capacitance, TIA_CF, afe4404_cap_table); + +static AFE440X_ATTR(in_intensity4_resistance, F_TIA_GAIN, afe4404_res_table); +static AFE440X_ATTR(in_intensity4_capacitance, TIA_CF, afe4404_cap_table); static struct attribute *afe440x_attributes[] = { - &afe440x_attr_tia_resistance1.dev_attr.attr, - &afe440x_attr_tia_capacitance1.dev_attr.attr, - &afe440x_attr_tia_resistance2.dev_attr.attr, - &afe440x_attr_tia_capacitance2.dev_attr.attr, - &dev_attr_tia_resistance_available.attr, - &dev_attr_tia_capacitance_available.attr, + &dev_attr_in_intensity_resistance_available.attr, + &dev_attr_in_intensity_capacitance_available.attr, + &afe440x_attr_in_intensity1_resistance.dev_attr.attr, + &afe440x_attr_in_intensity1_capacitance.dev_attr.attr, + &afe440x_attr_in_intensity2_resistance.dev_attr.attr, + &afe440x_attr_in_intensity2_capacitance.dev_attr.attr, + &afe440x_attr_in_intensity3_resistance.dev_attr.attr, + &afe440x_attr_in_intensity3_capacitance.dev_attr.attr, + &afe440x_attr_in_intensity4_resistance.dev_attr.attr, + &afe440x_attr_in_intensity4_capacitance.dev_attr.attr, NULL }; -- cgit v1.3-14-g43fede From 6994aea7842d824a8cc38c950ddcab3f8a75c278 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 25 Apr 2016 16:15:53 +0300 Subject: Documentation: iio: Add IIO software devices docs Signed-off-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/configfs-iio | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/configfs-iio b/Documentation/ABI/testing/configfs-iio index 2483756fccf5..aebda53ec0f7 100644 --- a/Documentation/ABI/testing/configfs-iio +++ b/Documentation/ABI/testing/configfs-iio @@ -19,3 +19,16 @@ KernelVersion: 4.4 Description: High resolution timers directory. Creating a directory here will result in creating a hrtimer trigger in the IIO subsystem. + +What: /config/iio/devices +Date: April 2016 +KernelVersion: 4.7 +Description: + Industrial IO software devices directory. + +What: /config/iio/devices/dummy +Date: April 2016 +KernelVersion: 4.7 +Description: + Dummy IIO devices directory. Creating a directory here will result + in creating a dummy IIO device in the IIO subystem. -- cgit v1.3-14-g43fede From b06d43f7a3db3ea4d62b3e0a299855c2a29ea18d Mon Sep 17 00:00:00 2001 From: Daniel Hung-yu Wu Date: Wed, 18 May 2016 14:55:12 -0700 Subject: Input: add Atmel Captouch Button driver Add I2C driver for Atmel Capacitive Touch Button device. Signed-off-by: Hung-yu Wu Signed-off-by: Grant Grundler Acked-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/atmel,captouch.txt | 36 +++ drivers/input/misc/Kconfig | 13 + drivers/input/misc/Makefile | 1 + drivers/input/misc/atmel_captouch.c | 290 +++++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/atmel,captouch.txt create mode 100644 drivers/input/misc/atmel_captouch.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/atmel,captouch.txt b/Documentation/devicetree/bindings/input/atmel,captouch.txt new file mode 100644 index 000000000000..fe9ee5c53bcc --- /dev/null +++ b/Documentation/devicetree/bindings/input/atmel,captouch.txt @@ -0,0 +1,36 @@ +Device tree bindings for Atmel capacitive touch device, typically +an Atmel touch sensor connected to AtmegaXX MCU running firmware +based on Qtouch library. + +The node for this device must be a child of a I2C controller node, as the +device communicates via I2C. + +Required properties: + + compatible: Must be "atmel,captouch". + reg: The I2C slave address of the device. + interrupts: Property describing the interrupt line the device + is connected to. The device only has one interrupt + source. + linux,keycodes: Specifies an array of numeric keycode values to + be used for reporting button presses. The array can + contain up to 8 entries. + +Optional properties: + + autorepeat: Enables the Linux input system's autorepeat + feature on the input device. + +Example: + + atmel-captouch@51 { + compatible = "atmel,captouch"; + reg = <0x51>; + interrupt-parent = <&tlmm>; + interrupts = <67 IRQ_TYPE_EDGE_FALLING>; + linux,keycodes = , , + , , + , , + , ; + autorepeat; + }; diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 1f2337abcf2f..9c3dfe79d4d4 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -82,6 +82,19 @@ config INPUT_ARIZONA_HAPTICS To compile this driver as a module, choose M here: the module will be called arizona-haptics. +config INPUT_ATMEL_CAPTOUCH + tristate "Atmel Capacitive Touch Button Driver" + depends on OF || COMPILE_TEST + help + Say Y here if an Atmel Capacitive Touch Button device which + implements "captouch" protocol is connected to I2C bus. Typically + this device consists of Atmel Touch sensor controlled by AtMegaXX + MCU running firmware based on Qtouch library. + One should find "atmel,captouch" node in the board specific DTS. + + To compile this driver as a module, choose M here: the + module will be called atmel_captouch. + config INPUT_BMA150 tristate "BMA150/SMB380 acceleration sensor support" depends on I2C diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 0357a088c6a9..5373f493f370 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_INPUT_APANEL) += apanel.o obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o +obj-$(CONFIG_INPUT_ATMEL_CAPTOUCH) += atmel_captouch.o obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o obj-$(CONFIG_INPUT_BMA150) += bma150.o obj-$(CONFIG_INPUT_CM109) += cm109.o diff --git a/drivers/input/misc/atmel_captouch.c b/drivers/input/misc/atmel_captouch.c new file mode 100644 index 000000000000..941265415a89 --- /dev/null +++ b/drivers/input/misc/atmel_captouch.c @@ -0,0 +1,290 @@ +/* + * Atmel Atmegaxx Capacitive Touch Button Driver + * + * Copyright (C) 2016 Google, inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * It's irrelevant that the HW used to develop captouch driver is based + * on Atmega88PA part and uses QtouchADC parts for sensing touch. + * Calling this driver "captouch" is an arbitrary way to distinguish + * the protocol this driver supported by other atmel/qtouch drivers. + * + * Captouch driver supports a newer/different version of the I2C + * registers/commands than the qt1070.c driver. + * Don't let the similarity of the general driver structure fool you. + * + * For raw i2c access from userspace, use i2cset/i2cget + * to poke at /dev/i2c-N devices. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Maximum number of buttons supported */ +#define MAX_NUM_OF_BUTTONS 8 + +/* Registers */ +#define REG_KEY1_THRESHOLD 0x02 +#define REG_KEY2_THRESHOLD 0x03 +#define REG_KEY3_THRESHOLD 0x04 +#define REG_KEY4_THRESHOLD 0x05 + +#define REG_KEY1_REF_H 0x20 +#define REG_KEY1_REF_L 0x21 +#define REG_KEY2_REF_H 0x22 +#define REG_KEY2_REF_L 0x23 +#define REG_KEY3_REF_H 0x24 +#define REG_KEY3_REF_L 0x25 +#define REG_KEY4_REF_H 0x26 +#define REG_KEY4_REF_L 0x27 + +#define REG_KEY1_DLT_H 0x30 +#define REG_KEY1_DLT_L 0x31 +#define REG_KEY2_DLT_H 0x32 +#define REG_KEY2_DLT_L 0x33 +#define REG_KEY3_DLT_H 0x34 +#define REG_KEY3_DLT_L 0x35 +#define REG_KEY4_DLT_H 0x36 +#define REG_KEY4_DLT_L 0x37 + +#define REG_KEY_STATE 0x3C + +/* + * @i2c_client: I2C slave device client pointer + * @input: Input device pointer + * @num_btn: Number of buttons + * @keycodes: map of button# to KeyCode + * @prev_btn: Previous key state to detect button "press" or "release" + * @xfer_buf: I2C transfer buffer + */ +struct atmel_captouch_device { + struct i2c_client *client; + struct input_dev *input; + u32 num_btn; + u32 keycodes[MAX_NUM_OF_BUTTONS]; + u8 prev_btn; + u8 xfer_buf[8] ____cacheline_aligned; +}; + +/* + * Read from I2C slave device + * The protocol is that the client has to provide both the register address + * and the length, and while reading back the device would prepend the data + * with address and length for verification. + */ +static int atmel_read(struct atmel_captouch_device *capdev, + u8 reg, u8 *data, size_t len) +{ + struct i2c_client *client = capdev->client; + struct device *dev = &client->dev; + struct i2c_msg msg[2]; + int err; + + if (len > sizeof(capdev->xfer_buf) - 2) + return -EINVAL; + + capdev->xfer_buf[0] = reg; + capdev->xfer_buf[1] = len; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].buf = capdev->xfer_buf; + msg[0].len = 2; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = capdev->xfer_buf; + msg[1].len = len + 2; + + err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (err != ARRAY_SIZE(msg)) + return err < 0 ? err : -EIO; + + if (capdev->xfer_buf[0] != reg) { + dev_err(dev, + "I2C read error: register address does not match (%#02x vs %02x)\n", + capdev->xfer_buf[0], reg); + return -ECOMM; + } + + memcpy(data, &capdev->xfer_buf[2], len); + + return 0; +} + +/* + * Handle interrupt and report the key changes to the input system. + * Multi-touch can be supported; however, it really depends on whether + * the device can multi-touch. + */ +static irqreturn_t atmel_captouch_isr(int irq, void *data) +{ + struct atmel_captouch_device *capdev = data; + struct device *dev = &capdev->client->dev; + int error; + int i; + u8 new_btn; + u8 changed_btn; + + error = atmel_read(capdev, REG_KEY_STATE, &new_btn, 1); + if (error) { + dev_err(dev, "failed to read button state: %d\n", error); + goto out; + } + + dev_dbg(dev, "%s: button state %#02x\n", __func__, new_btn); + + changed_btn = new_btn ^ capdev->prev_btn; + capdev->prev_btn = new_btn; + + for (i = 0; i < capdev->num_btn; i++) { + if (changed_btn & BIT(i)) + input_report_key(capdev->input, + capdev->keycodes[i], + new_btn & BIT(i)); + } + + input_sync(capdev->input); + +out: + return IRQ_HANDLED; +} + +/* + * Probe function to setup the device, input system and interrupt + */ +static int atmel_captouch_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct atmel_captouch_device *capdev; + struct device *dev = &client->dev; + struct device_node *node; + int i; + int err; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + dev_err(dev, "needed i2c functionality is not supported\n"); + return -EINVAL; + } + + capdev = devm_kzalloc(dev, sizeof(*capdev), GFP_KERNEL); + if (!capdev) + return -ENOMEM; + + capdev->client = client; + i2c_set_clientdata(client, capdev); + + err = atmel_read(capdev, REG_KEY_STATE, + &capdev->prev_btn, sizeof(capdev->prev_btn)); + if (err) { + dev_err(dev, "failed to read initial button state: %d\n", err); + return err; + } + + capdev->input = devm_input_allocate_device(dev); + if (!capdev->input) { + dev_err(dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + capdev->input->id.bustype = BUS_I2C; + capdev->input->id.product = 0x880A; + capdev->input->id.version = 0; + capdev->input->name = "ATMegaXX Capacitive Button Controller"; + __set_bit(EV_KEY, capdev->input->evbit); + + node = dev->of_node; + if (!node) { + dev_err(dev, "failed to find matching node in device tree\n"); + return -EINVAL; + } + + if (of_property_read_bool(node, "autorepeat")) + __set_bit(EV_REP, capdev->input->evbit); + + capdev->num_btn = of_property_count_u32_elems(node, "linux,keymap"); + if (capdev->num_btn > MAX_NUM_OF_BUTTONS) + capdev->num_btn = MAX_NUM_OF_BUTTONS; + + err = of_property_read_u32_array(node, "linux,keycodes", + capdev->keycodes, + capdev->num_btn); + if (err) { + dev_err(dev, + "failed to read linux,keycode property: %d\n", err); + return err; + } + + for (i = 0; i < capdev->num_btn; i++) + __set_bit(capdev->keycodes[i], capdev->input->keybit); + + capdev->input->keycode = capdev->keycodes; + capdev->input->keycodesize = sizeof(capdev->keycodes[0]); + capdev->input->keycodemax = capdev->num_btn; + + err = input_register_device(capdev->input); + if (err) + return err; + + err = devm_request_threaded_irq(dev, client->irq, + NULL, atmel_captouch_isr, + IRQF_ONESHOT, + "atmel_captouch", capdev); + if (err) { + dev_err(dev, "failed to request irq %d: %d\n", + client->irq, err); + return err; + } + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id atmel_captouch_of_id[] = { + { + .compatible = "atmel,captouch", + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, atmel_captouch_of_id); +#endif + +static const struct i2c_device_id atmel_captouch_id[] = { + { "atmel_captouch", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, atmel_captouch_id); + +static struct i2c_driver atmel_captouch_driver = { + .probe = atmel_captouch_probe, + .id_table = atmel_captouch_id, + .driver = { + .name = "atmel_captouch", + .of_match_table = of_match_ptr(atmel_captouch_of_id), + }, +}; +module_i2c_driver(atmel_captouch_driver); + +/* Module information */ +MODULE_AUTHOR("Hung-yu Wu "); +MODULE_DESCRIPTION("Atmel ATmegaXX Capacitance Touch Sensor I2C Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.3-14-g43fede From 14fe29e8ef44a175db2d803a0b7f0aa6c372631a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 24 May 2016 14:45:15 +0200 Subject: drm/doc: Drop vblank_disable_allow wording Forgot to update the docs when nuking that. Oops. Fixes: fcee59065e58 ("drm: Nuke ->vblank_disable_allowed") Signed-off-by: Daniel Vetter Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1464093915-3935-1-git-send-email-daniel.vetter@ffwll.ch --- Documentation/DocBook/gpu.tmpl | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 4a0c599b6a6d..90dbdb5087c4 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -2839,14 +2839,7 @@ void (*disable_vblank) (struct drm_device *dev, int crtc); Drivers must initialize the vertical blanking handling core with a call to drm_vblank_init in their - load operation. The function will set the struct - drm_device - vblank_disable_allowed field to 0. This will - keep vertical blanking interrupts enabled permanently until the first mode - set operation, where vblank_disable_allowed is - set to 1. The reason behind this is not clear. Drivers can set the field - to 1 after calling drm_vblank_init to make vertical - blanking interrupts dynamically managed from the beginning. + load operation. Vertical blanking interrupts can be enabled by the DRM core or by drivers -- cgit v1.3-14-g43fede From 48a2b783483b3ed9565348736a5148a11cfffad6 Mon Sep 17 00:00:00 2001 From: Jeffrey Lin Date: Thu, 31 Mar 2016 17:03:33 -0700 Subject: Input: add Raydium I2C touchscreen driver This adds support for Raydium I2C touch controllers compatible with RM32380. Signed-off-by: Jeffrey Lin Acked-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/raydium_i2c_ts.txt | 20 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/input/touchscreen/Kconfig | 13 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/raydium_i2c_ts.c | 1215 ++++++++++++++++++++ 5 files changed, 1250 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/raydium_i2c_ts.txt create mode 100644 drivers/input/touchscreen/raydium_i2c_ts.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/input/raydium_i2c_ts.txt b/Documentation/devicetree/bindings/input/raydium_i2c_ts.txt new file mode 100644 index 000000000000..5b6232db7c61 --- /dev/null +++ b/Documentation/devicetree/bindings/input/raydium_i2c_ts.txt @@ -0,0 +1,20 @@ +Raydium I2C touchscreen + +Required properties: +- compatible: must be "raydium,rm32380" +- reg: The I2C address of the device +- interrupt-parent: the phandle for the interrupt controller +- interrupts: interrupt to which the chip is connected + See ../interrupt-controller/interrupts.txt +Optional properties: +- avdd-supply: analog power supply needed to power device +- vccio-supply: IO Power source +- reset-gpios: reset gpio the chip is connected to. + +Example: + touchscreen@39 { + compatible = "raydium,rm32380"; + reg = <0x39>; + interrupt-parent = <&gpio>; + interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 656f3dd31f19..9d28331aac5a 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -191,6 +191,7 @@ raidsonic RaidSonic Technology GmbH ralink Mediatek/Ralink Technology Corp. ramtron Ramtron International raspberrypi Raspberry Pi Foundation +raydium Raydium Semiconductor Corp. realtek Realtek Semiconductor Corp. renesas Renesas Electronics Corporation richtek Richtek Technology Corporation diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index c3880b9e4b61..ac5aa12ac190 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1037,6 +1037,19 @@ config TOUCHSCREEN_PCAP To compile this driver as a module, choose M here: the module will be called pcap_ts. +config TOUCHSCREEN_RM_TS + tristate "Raydium I2C Touchscreen" + depends on I2C + depends on GPIOLIB || COMPILE_TEST + help + Say Y here if you have Raydium series I2C touchscreen, + such as RM32380, connected to your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called raydium_i2c_ts. + config TOUCHSCREEN_ST1232 tristate "Sitronix ST1232 touchscreen controllers" depends on I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 75af04d7db83..d17d57d827b9 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o +obj-$(CONFIG_TOUCHSCREEN_RM_TS) += raydium_i2c_ts.o obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c new file mode 100644 index 000000000000..1ae65f647224 --- /dev/null +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -0,0 +1,1215 @@ +/* + * Raydium touchscreen I2C driver. + * + * Copyright (C) 2012-2014, Raydium Semiconductor Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Raydium reserves the right to make changes without further notice + * to the materials described herein. Raydium does not assume any + * liability arising out of the application described herein. + * + * Contact Raydium Semiconductor Corporation at www.rad-ic.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Slave I2C mode */ +#define RM_BOOT_BLDR 0x02 +#define RM_BOOT_MAIN 0x03 + +/* I2C bootoloader commands */ +#define RM_CMD_BOOT_PAGE_WRT 0x0B /* send bl page write */ +#define RM_CMD_BOOT_WRT 0x11 /* send bl write */ +#define RM_CMD_BOOT_ACK 0x22 /* send ack*/ +#define RM_CMD_BOOT_CHK 0x33 /* send data check */ +#define RM_CMD_BOOT_READ 0x44 /* send wait bl data ready*/ + +#define RM_BOOT_RDY 0xFF /* bl data ready */ + +/* I2C main commands */ +#define RM_CMD_QUERY_BANK 0x2B +#define RM_CMD_DATA_BANK 0x4D +#define RM_CMD_ENTER_SLEEP 0x4E +#define RM_CMD_BANK_SWITCH 0xAA + +#define RM_RESET_MSG_ADDR 0x40000004 + +#define RM_MAX_READ_SIZE 56 + +/* Touch relative info */ +#define RM_MAX_RETRIES 3 +#define RM_MAX_TOUCH_NUM 10 +#define RM_BOOT_DELAY_MS 100 + +/* Offsets in contact data */ +#define RM_CONTACT_STATE_POS 0 +#define RM_CONTACT_X_POS 1 +#define RM_CONTACT_Y_POS 3 +#define RM_CONTACT_PRESSURE_POS 5 +#define RM_CONTACT_WIDTH_X_POS 6 +#define RM_CONTACT_WIDTH_Y_POS 7 + +/* Bootloader relative info */ +#define RM_BL_WRT_CMD_SIZE 3 /* bl flash wrt cmd size */ +#define RM_BL_WRT_PKG_SIZE 32 /* bl wrt pkg size */ +#define RM_BL_WRT_LEN (RM_BL_WRT_PKG_SIZE + RM_BL_WRT_CMD_SIZE) +#define RM_FW_PAGE_SIZE 128 +#define RM_MAX_FW_RETRIES 30 +#define RM_MAX_FW_SIZE 0xD000 + +#define RM_POWERON_DELAY_USEC 500 +#define RM_RESET_DELAY_MSEC 50 + +enum raydium_bl_cmd { + BL_HEADER = 0, + BL_PAGE_STR, + BL_PKG_IDX, + BL_DATA_STR, +}; + +enum raydium_bl_ack { + RAYDIUM_ACK_NULL = 0, + RAYDIUM_WAIT_READY, + RAYDIUM_PATH_READY, +}; + +enum raydium_boot_mode { + RAYDIUM_TS_MAIN = 0, + RAYDIUM_TS_BLDR, +}; + +/* Response to RM_CMD_DATA_BANK request */ +struct raydium_data_info { + __le32 data_bank_addr; + u8 pkg_size; + u8 tp_info_size; +}; + +struct raydium_info { + __le32 hw_ver; /*device version */ + u8 main_ver; + u8 sub_ver; + __le16 ft_ver; /* test version */ + u8 x_num; + u8 y_num; + __le16 x_max; + __le16 y_max; + u8 x_res; /* units/mm */ + u8 y_res; /* units/mm */ +}; + +/* struct raydium_data - represents state of Raydium touchscreen device */ +struct raydium_data { + struct i2c_client *client; + struct input_dev *input; + + struct regulator *avdd; + struct regulator *vccio; + struct gpio_desc *reset_gpio; + + struct raydium_info info; + + struct mutex sysfs_mutex; + + u8 *report_data; + + u32 data_bank_addr; + u8 report_size; + u8 contact_size; + + enum raydium_boot_mode boot_mode; + + bool wake_irq_enabled; +}; + +static int raydium_i2c_send(struct i2c_client *client, + u8 addr, const void *data, size_t len) +{ + u8 *buf; + int tries = 0; + int ret; + + buf = kmalloc(len + 1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf[0] = addr; + memcpy(buf + 1, data, len); + + do { + ret = i2c_master_send(client, buf, len + 1); + if (likely(ret == len + 1)) + break; + + msleep(20); + } while (++tries < RM_MAX_RETRIES); + + kfree(buf); + + if (unlikely(ret != len + 1)) { + if (ret >= 0) + ret = -EIO; + dev_err(&client->dev, "%s failed: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +static int raydium_i2c_read(struct i2c_client *client, + u8 addr, void *data, size_t len) +{ + struct i2c_msg xfer[] = { + { + .addr = client->addr, + .len = 1, + .buf = &addr, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = len, + .buf = data, + } + }; + int ret; + + ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer)); + if (unlikely(ret != ARRAY_SIZE(xfer))) + return ret < 0 ? ret : -EIO; + + return 0; +} + +static int raydium_i2c_read_message(struct i2c_client *client, + u32 addr, void *data, size_t len) +{ + __be32 be_addr; + size_t xfer_len; + int error; + + while (len) { + xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); + + be_addr = cpu_to_be32(addr); + + error = raydium_i2c_send(client, RM_CMD_BANK_SWITCH, + &be_addr, sizeof(be_addr)); + if (!error) + error = raydium_i2c_read(client, addr & 0xff, + data, xfer_len); + if (error) + return error; + + len -= xfer_len; + data += xfer_len; + addr += xfer_len; + } + + return 0; +} + +static int raydium_i2c_send_message(struct i2c_client *client, + u32 addr, const void *data, size_t len) +{ + __be32 be_addr = cpu_to_be32(addr); + int error; + + error = raydium_i2c_send(client, RM_CMD_BANK_SWITCH, + &be_addr, sizeof(be_addr)); + if (!error) + error = raydium_i2c_send(client, addr & 0xff, data, len); + + return error; +} + +static int raydium_i2c_sw_reset(struct i2c_client *client) +{ + const u8 soft_rst_cmd = 0x01; + int error; + + error = raydium_i2c_send_message(client, RM_RESET_MSG_ADDR, + &soft_rst_cmd, sizeof(soft_rst_cmd)); + if (error) { + dev_err(&client->dev, "software reset failed: %d\n", error); + return error; + } + + msleep(RM_RESET_DELAY_MSEC); + + return 0; +} + +static int raydium_i2c_query_ts_info(struct raydium_data *ts) +{ + struct i2c_client *client = ts->client; + struct raydium_data_info data_info; + __le32 query_bank_addr; + + int error, retry_cnt; + + for (retry_cnt = 0; retry_cnt < RM_MAX_RETRIES; retry_cnt++) { + error = raydium_i2c_read(client, RM_CMD_DATA_BANK, + &data_info, sizeof(data_info)); + if (error) + continue; + + /* + * Warn user if we already allocated memory for reports and + * then the size changed (due to firmware update?) and keep + * old size instead. + */ + if (ts->report_data && ts->report_size != data_info.pkg_size) + dev_warn(&client->dev, + "report size changes, was: %d, new: %d\n", + ts->report_size, data_info.pkg_size); + else + ts->report_size = data_info.pkg_size; + + ts->contact_size = data_info.tp_info_size; + ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr); + + dev_dbg(&client->dev, + "data_bank_addr: %#08x, report_size: %d, contact_size: %d\n", + ts->data_bank_addr, ts->report_size, ts->contact_size); + + error = raydium_i2c_read(client, RM_CMD_QUERY_BANK, + &query_bank_addr, + sizeof(query_bank_addr)); + if (error) + continue; + + error = raydium_i2c_read_message(client, + le32_to_cpu(query_bank_addr), + &ts->info, sizeof(ts->info)); + if (error) + continue; + + return 0; + } + + dev_err(&client->dev, "failed to query device parameters: %d\n", error); + return error; +} + +static int raydium_i2c_check_fw_status(struct raydium_data *ts) +{ + struct i2c_client *client = ts->client; + static const u8 bl_ack = 0x62; + static const u8 main_ack = 0x66; + u8 buf[4]; + int error; + + error = raydium_i2c_read(client, RM_CMD_BOOT_READ, buf, sizeof(buf)); + if (!error) { + if (buf[0] == bl_ack) + ts->boot_mode = RAYDIUM_TS_BLDR; + else if (buf[0] == main_ack) + ts->boot_mode = RAYDIUM_TS_MAIN; + return 0; + } + + return error; +} + +static int raydium_i2c_initialize(struct raydium_data *ts) +{ + struct i2c_client *client = ts->client; + int error, retry_cnt; + + for (retry_cnt = 0; retry_cnt < RM_MAX_RETRIES; retry_cnt++) { + /* Wait for Hello packet */ + msleep(RM_BOOT_DELAY_MS); + + error = raydium_i2c_check_fw_status(ts); + if (error) { + dev_err(&client->dev, + "failed to read 'hello' packet: %d\n", error); + continue; + } + + if (ts->boot_mode == RAYDIUM_TS_BLDR || + ts->boot_mode == RAYDIUM_TS_MAIN) { + break; + } + } + + if (error) + ts->boot_mode = RAYDIUM_TS_BLDR; + + if (ts->boot_mode == RAYDIUM_TS_BLDR) { + ts->info.hw_ver = cpu_to_le32(0xffffffffUL); + ts->info.main_ver = 0xff; + ts->info.sub_ver = 0xff; + } else { + raydium_i2c_query_ts_info(ts); + } + + return error; +} + +static int raydium_i2c_bl_chk_state(struct i2c_client *client, + enum raydium_bl_ack state) +{ + static const u8 ack_ok[] = { 0xFF, 0x39, 0x30, 0x30, 0x54 }; + u8 rbuf[sizeof(ack_ok)]; + u8 retry; + int error; + + for (retry = 0; retry < RM_MAX_FW_RETRIES; retry++) { + switch (state) { + case RAYDIUM_ACK_NULL: + return 0; + + case RAYDIUM_WAIT_READY: + error = raydium_i2c_read(client, RM_CMD_BOOT_CHK, + &rbuf[0], 1); + if (!error && rbuf[0] == RM_BOOT_RDY) + return 0; + + break; + + case RAYDIUM_PATH_READY: + error = raydium_i2c_read(client, RM_CMD_BOOT_CHK, + rbuf, sizeof(rbuf)); + if (!error && !memcmp(rbuf, ack_ok, sizeof(ack_ok))) + return 0; + + break; + + default: + dev_err(&client->dev, "%s: invalid target state %d\n", + __func__, state); + return -EINVAL; + } + + msleep(20); + } + + return -ETIMEDOUT; +} + +static int raydium_i2c_write_object(struct i2c_client *client, + const void *data, size_t len, + enum raydium_bl_ack state) +{ + int error; + + error = raydium_i2c_send(client, RM_CMD_BOOT_WRT, data, len); + if (error) { + dev_err(&client->dev, "WRT obj command failed: %d\n", + error); + return error; + } + + error = raydium_i2c_send(client, RM_CMD_BOOT_ACK, NULL, 0); + if (error) { + dev_err(&client->dev, "Ack obj command failed: %d\n", error); + return error; + } + + error = raydium_i2c_bl_chk_state(client, state); + if (error) { + dev_err(&client->dev, "BL check state failed: %d\n", error); + return error; + } + return 0; +} + +static bool raydium_i2c_boot_trigger(struct i2c_client *client) +{ + static const u8 cmd[7][6] = { + { 0x08, 0x0C, 0x09, 0x00, 0x50, 0xD7 }, + { 0x08, 0x04, 0x09, 0x00, 0x50, 0xA5 }, + { 0x08, 0x04, 0x09, 0x00, 0x50, 0x00 }, + { 0x08, 0x04, 0x09, 0x00, 0x50, 0xA5 }, + { 0x08, 0x0C, 0x09, 0x00, 0x50, 0x00 }, + { 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0xA2, 0x00, 0x00, 0x00, 0x00 }, + }; + int i; + int error; + + for (i = 0; i < 7; i++) { + error = raydium_i2c_write_object(client, cmd[i], sizeof(cmd[i]), + RAYDIUM_WAIT_READY); + if (error) { + dev_err(&client->dev, + "boot trigger failed at step %d: %d\n", + i, error); + return error; + } + } + + return 0; +} + +static bool raydium_i2c_fw_trigger(struct i2c_client *client) +{ + static const u8 cmd[5][11] = { + { 0, 0x09, 0x71, 0x0C, 0x09, 0x00, 0x50, 0xD7, 0, 0, 0 }, + { 0, 0x09, 0x71, 0x04, 0x09, 0x00, 0x50, 0xA5, 0, 0, 0 }, + { 0, 0x09, 0x71, 0x04, 0x09, 0x00, 0x50, 0x00, 0, 0, 0 }, + { 0, 0x09, 0x71, 0x04, 0x09, 0x00, 0x50, 0xA5, 0, 0, 0 }, + { 0, 0x09, 0x71, 0x0C, 0x09, 0x00, 0x50, 0x00, 0, 0, 0 }, + }; + int i; + int error; + + for (i = 0; i < 5; i++) { + error = raydium_i2c_write_object(client, cmd[i], sizeof(cmd[i]), + RAYDIUM_ACK_NULL); + if (error) { + dev_err(&client->dev, + "fw trigger failed at step %d: %d\n", + i, error); + return error; + } + } + + return 0; +} + +static int raydium_i2c_check_path(struct i2c_client *client) +{ + static const u8 cmd[] = { 0x09, 0x00, 0x09, 0x00, 0x50, 0x10, 0x00 }; + int error; + + error = raydium_i2c_write_object(client, cmd, sizeof(cmd), + RAYDIUM_PATH_READY); + if (error) { + dev_err(&client->dev, "check path command failed: %d\n", error); + return error; + } + + return 0; +} + +static int raydium_i2c_enter_bl(struct i2c_client *client) +{ + static const u8 cal_cmd[] = { 0x00, 0x01, 0x52 }; + int error; + + error = raydium_i2c_write_object(client, cal_cmd, sizeof(cal_cmd), + RAYDIUM_ACK_NULL); + if (error) { + dev_err(&client->dev, "enter bl command failed: %d\n", error); + return error; + } + + msleep(RM_BOOT_DELAY_MS); + return 0; +} + +static int raydium_i2c_leave_bl(struct i2c_client *client) +{ + static const u8 leave_cmd[] = { 0x05, 0x00 }; + int error; + + error = raydium_i2c_write_object(client, leave_cmd, sizeof(leave_cmd), + RAYDIUM_ACK_NULL); + if (error) { + dev_err(&client->dev, "leave bl command failed: %d\n", error); + return error; + } + + msleep(RM_BOOT_DELAY_MS); + return 0; +} + +static int raydium_i2c_write_checksum(struct i2c_client *client, + size_t length, u16 checksum) +{ + u8 checksum_cmd[] = { 0x00, 0x05, 0x6D, 0x00, 0x00, 0x00, 0x00 }; + int error; + + put_unaligned_le16(length, &checksum_cmd[3]); + put_unaligned_le16(checksum, &checksum_cmd[5]); + + error = raydium_i2c_write_object(client, + checksum_cmd, sizeof(checksum_cmd), + RAYDIUM_ACK_NULL); + if (error) { + dev_err(&client->dev, "failed to write checksum: %d\n", + error); + return error; + } + + return 0; +} + +static int raydium_i2c_disable_watch_dog(struct i2c_client *client) +{ + static const u8 cmd[] = { 0x0A, 0xAA }; + int error; + + error = raydium_i2c_write_object(client, cmd, sizeof(cmd), + RAYDIUM_WAIT_READY); + if (error) { + dev_err(&client->dev, "disable watchdog command failed: %d\n", + error); + return error; + } + + return 0; +} + +static int raydium_i2c_fw_write_page(struct i2c_client *client, + u16 page_idx, const void *data, size_t len) +{ + u8 buf[RM_BL_WRT_LEN]; + size_t xfer_len; + int error; + int i; + + BUILD_BUG_ON((RM_FW_PAGE_SIZE % RM_BL_WRT_PKG_SIZE) != 0); + + for (i = 0; i < RM_FW_PAGE_SIZE / RM_BL_WRT_PKG_SIZE; i++) { + buf[BL_HEADER] = RM_CMD_BOOT_PAGE_WRT; + buf[BL_PAGE_STR] = page_idx ? 0xff : 0; + buf[BL_PKG_IDX] = i + 1; + + xfer_len = min_t(size_t, len, RM_BL_WRT_PKG_SIZE); + memcpy(&buf[BL_DATA_STR], data, xfer_len); + if (len < RM_BL_WRT_PKG_SIZE) + memset(&buf[BL_DATA_STR + xfer_len], 0xff, + RM_BL_WRT_PKG_SIZE - xfer_len); + + error = raydium_i2c_write_object(client, buf, RM_BL_WRT_LEN, + RAYDIUM_WAIT_READY); + if (error) { + dev_err(&client->dev, + "page write command failed for page %d, chunk %d: %d\n", + page_idx, i, error); + return error; + } + + data += xfer_len; + len -= xfer_len; + } + + return error; +} + +static int raydium_i2c_do_update_firmware(struct raydium_data *ts, + const struct firmware *fw) +{ + struct i2c_client *client = ts->client; + const void *data; + size_t data_len; + size_t len; + int page_nr; + int i; + int error; + u16 fw_checksum; + + if (fw->size == 0 || fw->size > RM_MAX_FW_SIZE) { + dev_err(&client->dev, "Invalid firmware length\n"); + return -EINVAL; + } + + error = raydium_i2c_check_fw_status(ts); + if (error) { + dev_err(&client->dev, "Unable to access IC %d\n", error); + return error; + } + + if (ts->boot_mode == RAYDIUM_TS_MAIN) { + for (i = 0; i < RM_MAX_RETRIES; i++) { + error = raydium_i2c_enter_bl(client); + if (!error) { + error = raydium_i2c_check_fw_status(ts); + if (error) { + dev_err(&client->dev, + "unable to access IC: %d\n", + error); + return error; + } + + if (ts->boot_mode == RAYDIUM_TS_BLDR) + break; + } + } + + if (ts->boot_mode == RAYDIUM_TS_MAIN) { + dev_err(&client->dev, + "failied to jump to boot loader: %d\n", + error); + return -EIO; + } + } + + error = raydium_i2c_disable_watch_dog(client); + if (error) + return error; + + error = raydium_i2c_check_path(client); + if (error) + return error; + + error = raydium_i2c_boot_trigger(client); + if (error) { + dev_err(&client->dev, "send boot trigger fail: %d\n", error); + return error; + } + + msleep(RM_BOOT_DELAY_MS); + + data = fw->data; + data_len = fw->size; + page_nr = 0; + + while (data_len) { + len = min_t(size_t, data_len, RM_FW_PAGE_SIZE); + + error = raydium_i2c_fw_write_page(client, page_nr++, data, len); + if (error) + return error; + + msleep(20); + + data += len; + data_len -= len; + } + + error = raydium_i2c_leave_bl(client); + if (error) { + dev_err(&client->dev, + "failed to leave boot loader: %d\n", error); + return error; + } + + dev_dbg(&client->dev, "left boot loader mode\n"); + msleep(RM_BOOT_DELAY_MS); + + error = raydium_i2c_check_fw_status(ts); + if (error) { + dev_err(&client->dev, + "failed to check fw status after write: %d\n", + error); + return error; + } + + if (ts->boot_mode != RAYDIUM_TS_MAIN) { + dev_err(&client->dev, + "failed to switch to main fw after writing firmware: %d\n", + error); + return -EINVAL; + } + + error = raydium_i2c_fw_trigger(client); + if (error) { + dev_err(&client->dev, "failed to trigger fw: %d\n", error); + return error; + } + + fw_checksum = 0; + for (i = 0; i < fw->size; i++) + fw_checksum += fw->data[i]; + + error = raydium_i2c_write_checksum(client, fw->size, fw_checksum); + if (error) + return error; + + return 0; +} + +static int raydium_i2c_fw_update(struct raydium_data *ts) +{ + struct i2c_client *client = ts->client; + const struct firmware *fw = NULL; + const char *fw_file = "raydium.fw"; + int error; + + error = request_firmware(&fw, fw_file, &client->dev); + if (error) { + dev_err(&client->dev, "Unable to open firmware %s\n", fw_file); + return error; + } + + disable_irq(client->irq); + + error = raydium_i2c_do_update_firmware(ts, fw); + if (error) { + dev_err(&client->dev, "firmware update failed: %d\n", error); + ts->boot_mode = RAYDIUM_TS_BLDR; + goto out_enable_irq; + } + + error = raydium_i2c_initialize(ts); + if (error) { + dev_err(&client->dev, + "failed to initialize device after firmware update: %d\n", + error); + ts->boot_mode = RAYDIUM_TS_BLDR; + goto out_enable_irq; + } + + ts->boot_mode = RAYDIUM_TS_MAIN; + +out_enable_irq: + enable_irq(client->irq); + msleep(100); + + release_firmware(fw); + + return error; +} + +static void raydium_mt_event(struct raydium_data *ts) +{ + int i; + int error; + + error = raydium_i2c_read_message(ts->client, ts->data_bank_addr, + ts->report_data, ts->report_size); + if (error) { + dev_err(&ts->client->dev, "%s: failed to read data: %d\n", + __func__, error); + return; + } + + for (i = 0; i < ts->report_size / ts->contact_size; i++) { + u8 *contact = &ts->report_data[ts->contact_size * i]; + bool state = contact[RM_CONTACT_STATE_POS]; + u8 wx, wy; + + input_mt_slot(ts->input, i); + input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, state); + + if (!state) + continue; + + input_report_abs(ts->input, ABS_MT_POSITION_X, + get_unaligned_le16(&contact[RM_CONTACT_X_POS])); + input_report_abs(ts->input, ABS_MT_POSITION_Y, + get_unaligned_le16(&contact[RM_CONTACT_Y_POS])); + input_report_abs(ts->input, ABS_MT_PRESSURE, + contact[RM_CONTACT_PRESSURE_POS]); + + wx = contact[RM_CONTACT_WIDTH_X_POS]; + wy = contact[RM_CONTACT_WIDTH_Y_POS]; + + input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, max(wx, wy)); + input_report_abs(ts->input, ABS_MT_TOUCH_MINOR, min(wx, wy)); + } + + input_mt_sync_frame(ts->input); + input_sync(ts->input); +} + +static irqreturn_t raydium_i2c_irq(int irq, void *_dev) +{ + struct raydium_data *ts = _dev; + + if (ts->boot_mode != RAYDIUM_TS_BLDR) + raydium_mt_event(ts); + + return IRQ_HANDLED; +} + +static ssize_t raydium_i2c_fw_ver_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + + return sprintf(buf, "%d.%d\n", ts->info.main_ver, ts->info.sub_ver); +} + +static ssize_t raydium_i2c_hw_ver_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + + return sprintf(buf, "%#04x\n", le32_to_cpu(ts->info.hw_ver)); +} + +static ssize_t raydium_i2c_boot_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + + return sprintf(buf, "%s\n", + ts->boot_mode == RAYDIUM_TS_MAIN ? + "Normal" : "Recovery"); +} + +static ssize_t raydium_i2c_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + int error; + + error = mutex_lock_interruptible(&ts->sysfs_mutex); + if (error) + return error; + + error = raydium_i2c_fw_update(ts); + + mutex_unlock(&ts->sysfs_mutex); + + return error ?: count; +} + +static ssize_t raydium_i2c_calibrate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + static const u8 cal_cmd[] = { 0x00, 0x01, 0x9E }; + int error; + + error = mutex_lock_interruptible(&ts->sysfs_mutex); + if (error) + return error; + + error = raydium_i2c_write_object(client, cal_cmd, sizeof(cal_cmd), + RAYDIUM_WAIT_READY); + if (error) + dev_err(&client->dev, "calibrate command failed: %d\n", error); + + mutex_unlock(&ts->sysfs_mutex); + return error ?: count; +} + +static DEVICE_ATTR(fw_version, S_IRUGO, raydium_i2c_fw_ver_show, NULL); +static DEVICE_ATTR(hw_version, S_IRUGO, raydium_i2c_hw_ver_show, NULL); +static DEVICE_ATTR(boot_mode, S_IRUGO, raydium_i2c_boot_mode_show, NULL); +static DEVICE_ATTR(update_fw, S_IWUSR, NULL, raydium_i2c_update_fw_store); +static DEVICE_ATTR(calibrate, S_IWUSR, NULL, raydium_i2c_calibrate_store); + +static struct attribute *raydium_i2c_attributes[] = { + &dev_attr_update_fw.attr, + &dev_attr_boot_mode.attr, + &dev_attr_fw_version.attr, + &dev_attr_hw_version.attr, + &dev_attr_calibrate.attr, + NULL +}; + +static struct attribute_group raydium_i2c_attribute_group = { + .attrs = raydium_i2c_attributes, +}; + +static void raydium_i2c_remove_sysfs_group(void *_data) +{ + struct raydium_data *ts = _data; + + sysfs_remove_group(&ts->client->dev.kobj, &raydium_i2c_attribute_group); +} + +static int raydium_i2c_power_on(struct raydium_data *ts) +{ + int error; + + if (IS_ERR_OR_NULL(ts->reset_gpio)) + return 0; + + gpiod_set_value_cansleep(ts->reset_gpio, 1); + + error = regulator_enable(ts->avdd); + if (error) { + dev_err(&ts->client->dev, + "failed to enable avdd regulator: %d\n", error); + goto release_reset_gpio; + } + + error = regulator_enable(ts->vccio); + if (error) { + regulator_disable(ts->avdd); + dev_err(&ts->client->dev, + "failed to enable vccio regulator: %d\n", error); + goto release_reset_gpio; + } + + udelay(RM_POWERON_DELAY_USEC); + +release_reset_gpio: + gpiod_set_value_cansleep(ts->reset_gpio, 0); + + if (error) + return error; + + msleep(RM_RESET_DELAY_MSEC); + + return 0; +} + +static void raydium_i2c_power_off(void *_data) +{ + struct raydium_data *ts = _data; + + if (!IS_ERR_OR_NULL(ts->reset_gpio)) { + gpiod_set_value_cansleep(ts->reset_gpio, 1); + regulator_disable(ts->vccio); + regulator_disable(ts->avdd); + } +} + +static int raydium_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + union i2c_smbus_data dummy; + struct raydium_data *ts; + int error; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, + "i2c check functionality error (need I2C_FUNC_I2C)\n"); + return -ENXIO; + } + + ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + mutex_init(&ts->sysfs_mutex); + + ts->client = client; + i2c_set_clientdata(client, ts); + + ts->avdd = devm_regulator_get(&client->dev, "avdd"); + if (IS_ERR(ts->avdd)) { + error = PTR_ERR(ts->avdd); + if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "Failed to get 'avdd' regulator: %d\n", error); + return error; + } + + ts->vccio = devm_regulator_get(&client->dev, "vccio"); + if (IS_ERR(ts->vccio)) { + error = PTR_ERR(ts->vccio); + if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "Failed to get 'vccio' regulator: %d\n", error); + return error; + } + + ts->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(ts->reset_gpio)) { + error = PTR_ERR(ts->reset_gpio); + if (error != -EPROBE_DEFER) { + dev_err(&client->dev, + "failed to get reset gpio: %d\n", error); + return error; + } + } + + error = raydium_i2c_power_on(ts); + if (error) + return error; + + error = devm_add_action(&client->dev, raydium_i2c_power_off, ts); + if (error) { + dev_err(&client->dev, + "failed to install power off action: %d\n", error); + raydium_i2c_power_off(ts); + return error; + } + + /* Make sure there is something at this address */ + if (i2c_smbus_xfer(client->adapter, client->addr, 0, + I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0) { + dev_err(&client->dev, "nothing at this address\n"); + return -ENXIO; + } + + error = raydium_i2c_initialize(ts); + if (error) { + dev_err(&client->dev, "failed to initialize: %d\n", error); + return error; + } + + ts->report_data = devm_kmalloc(&client->dev, + ts->report_size, GFP_KERNEL); + if (!ts->report_data) + return -ENOMEM; + + ts->input = devm_input_allocate_device(&client->dev); + if (!ts->input) { + dev_err(&client->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + ts->input->name = "Raydium Touchscreen"; + ts->input->id.bustype = BUS_I2C; + + input_set_drvdata(ts->input, ts); + + input_set_abs_params(ts->input, ABS_MT_POSITION_X, + 0, le16_to_cpu(ts->info.x_max), 0, 0); + input_set_abs_params(ts->input, ABS_MT_POSITION_Y, + 0, le16_to_cpu(ts->info.y_max), 0, 0); + input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->info.x_res); + input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->info.y_res); + + input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0); + + error = input_mt_init_slots(ts->input, RM_MAX_TOUCH_NUM, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(&client->dev, + "failed to initialize MT slots: %d\n", error); + return error; + } + + error = input_register_device(ts->input); + if (error) { + dev_err(&client->dev, + "unable to register input device: %d\n", error); + return error; + } + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, raydium_i2c_irq, + IRQF_ONESHOT, client->name, ts); + if (error) { + dev_err(&client->dev, "Failed to register interrupt\n"); + return error; + } + + error = sysfs_create_group(&client->dev.kobj, + &raydium_i2c_attribute_group); + if (error) { + dev_err(&client->dev, "failed to create sysfs attributes: %d\n", + error); + return error; + } + + error = devm_add_action(&client->dev, + raydium_i2c_remove_sysfs_group, ts); + if (error) { + raydium_i2c_remove_sysfs_group(ts); + dev_err(&client->dev, + "Failed to add sysfs cleanup action: %d\n", error); + return error; + } + + return 0; +} + +static void __maybe_unused raydium_enter_sleep(struct i2c_client *client) +{ + static const u8 sleep_cmd[] = { 0x5A, 0xff, 0x00, 0x0f }; + int error; + + error = raydium_i2c_send(client, RM_CMD_ENTER_SLEEP, + sleep_cmd, sizeof(sleep_cmd)); + if (error) + dev_err(&client->dev, + "sleep command failed: %d\n", error); +} + +static int __maybe_unused raydium_i2c_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + + /* Sleep is not available in BLDR recovery mode */ + if (ts->boot_mode != RAYDIUM_TS_MAIN) + return -ENOMEM; + + disable_irq(client->irq); + + if (device_may_wakeup(dev)) { + raydium_enter_sleep(client); + + ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0); + } else { + raydium_i2c_power_off(ts); + } + + return 0; +} + +static int __maybe_unused raydium_i2c_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct raydium_data *ts = i2c_get_clientdata(client); + + if (device_may_wakeup(dev)) { + if (ts->wake_irq_enabled) + disable_irq_wake(client->irq); + raydium_i2c_sw_reset(client); + } else { + raydium_i2c_power_on(ts); + raydium_i2c_initialize(ts); + } + + enable_irq(client->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(raydium_i2c_pm_ops, + raydium_i2c_suspend, raydium_i2c_resume); + +static const struct i2c_device_id raydium_i2c_id[] = { + { "raydium_i2c" , 0 }, + { "rm32380", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(i2c, raydium_i2c_id); + +#ifdef CONFIG_ACPI +static const struct acpi_device_id raydium_acpi_id[] = { + { "RAYD0001", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(acpi, raydium_acpi_id); +#endif + +#ifdef CONFIG_OF +static const struct of_device_id raydium_of_match[] = { + { .compatible = "raydium,rm32380", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, raydium_of_match); +#endif + +static struct i2c_driver raydium_i2c_driver = { + .probe = raydium_i2c_probe, + .id_table = raydium_i2c_id, + .driver = { + .name = "raydium_ts", + .pm = &raydium_i2c_pm_ops, + .acpi_match_table = ACPI_PTR(raydium_acpi_id), + .of_match_table = of_match_ptr(raydium_of_match), + }, +}; +module_i2c_driver(raydium_i2c_driver); + +MODULE_AUTHOR("Raydium"); +MODULE_DESCRIPTION("Raydium I2c Touchscreen driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.3-14-g43fede From e039e2f5b4dab9a90bb5441a154c01a051b1abfa Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Tue, 19 Apr 2016 11:18:32 +0200 Subject: iio:st_pressure:initial lps22hb sensor support Initial support for ST LPS22HB pressure sensor. Datasheet: http://www2.st.com/resource/en/datasheet/lps22hb.pdf Features: * pressure data and timestamping channels * sampling frequency selection * interrupt based trigger * over I2C or SPI Signed-off-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/st-sensors.txt | 1 + drivers/iio/pressure/Kconfig | 2 +- drivers/iio/pressure/st_pressure.h | 1 + drivers/iio/pressure/st_pressure_core.c | 93 +++++++++++++++++++++- drivers/iio/pressure/st_pressure_i2c.c | 4 + drivers/iio/pressure/st_pressure_spi.c | 1 + 6 files changed, 97 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index 5844cf72862d..e41fe340162b 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -64,3 +64,4 @@ Pressure sensors: - st,lps001wp-press - st,lps25h-press - st,lps331ap-press +- st,lps22hb-press diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 9125a9382b3e..8d654f671b6b 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -131,7 +131,7 @@ config IIO_ST_PRESS select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) help Say yes here to build support for STMicroelectronics pressure - sensors: LPS001WP, LPS25H, LPS331AP. + sensors: LPS001WP, LPS25H, LPS331AP, LPS22HB. This driver can also be built as a module. If so, these modules will be created: diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index f5f41490060b..903a21e46874 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -17,6 +17,7 @@ #define LPS001WP_PRESS_DEV_NAME "lps001wp" #define LPS25H_PRESS_DEV_NAME "lps25h" #define LPS331AP_PRESS_DEV_NAME "lps331ap" +#define LPS22HB_PRESS_DEV_NAME "lps22hb" /** * struct st_sensors_platform_data - default press platform data diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 9e9b72a8f18f..c0ff3bf071d8 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -113,6 +113,26 @@ #define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28 #define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b +/* CUSTOM VALUES FOR LPS22HB SENSOR */ +#define ST_PRESS_LPS22HB_WAI_EXP 0xb1 +#define ST_PRESS_LPS22HB_ODR_ADDR 0x10 +#define ST_PRESS_LPS22HB_ODR_MASK 0x70 +#define ST_PRESS_LPS22HB_ODR_AVL_1HZ_VAL 0x01 +#define ST_PRESS_LPS22HB_ODR_AVL_10HZ_VAL 0x02 +#define ST_PRESS_LPS22HB_ODR_AVL_25HZ_VAL 0x03 +#define ST_PRESS_LPS22HB_ODR_AVL_50HZ_VAL 0x04 +#define ST_PRESS_LPS22HB_ODR_AVL_75HZ_VAL 0x05 +#define ST_PRESS_LPS22HB_PW_ADDR 0x10 +#define ST_PRESS_LPS22HB_PW_MASK 0x70 +#define ST_PRESS_LPS22HB_BDU_ADDR 0x10 +#define ST_PRESS_LPS22HB_BDU_MASK 0x02 +#define ST_PRESS_LPS22HB_DRDY_IRQ_ADDR 0x12 +#define ST_PRESS_LPS22HB_DRDY_IRQ_INT1_MASK 0x04 +#define ST_PRESS_LPS22HB_DRDY_IRQ_INT2_MASK 0x08 +#define ST_PRESS_LPS22HB_IHL_IRQ_ADDR 0x12 +#define ST_PRESS_LPS22HB_IHL_IRQ_MASK 0x80 +#define ST_PRESS_LPS22HB_MULTIREAD_BIT true + static const struct iio_chan_spec st_press_1_channels[] = { { .type = IIO_PRESSURE, @@ -183,6 +203,27 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1) }; +static const struct iio_chan_spec st_press_lps22hb_channels[] = { + { + .type = IIO_PRESSURE, + .channel2 = IIO_NO_MOD, + .address = ST_PRESS_1_OUT_XL_ADDR, + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 24, + .storagebits = 24, + .endianness = IIO_LE, + }, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .modified = 0, + }, + IIO_CHAN_SOFT_TIMESTAMP(1) +}; + static const struct st_sensor_settings st_press_sensors_settings[] = { { .wai = ST_PRESS_LPS331AP_WAI_EXP, @@ -326,6 +367,51 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { .multi_read_bit = ST_PRESS_LPS25H_MULTIREAD_BIT, .bootime = 2, }, + { + .wai = ST_PRESS_LPS22HB_WAI_EXP, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LPS22HB_PRESS_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_press_lps22hb_channels, + .num_ch = ARRAY_SIZE(st_press_lps22hb_channels), + .odr = { + .addr = ST_PRESS_LPS22HB_ODR_ADDR, + .mask = ST_PRESS_LPS22HB_ODR_MASK, + .odr_avl = { + { 1, ST_PRESS_LPS22HB_ODR_AVL_1HZ_VAL, }, + { 10, ST_PRESS_LPS22HB_ODR_AVL_10HZ_VAL, }, + { 25, ST_PRESS_LPS22HB_ODR_AVL_25HZ_VAL, }, + { 50, ST_PRESS_LPS22HB_ODR_AVL_50HZ_VAL, }, + { 75, ST_PRESS_LPS22HB_ODR_AVL_75HZ_VAL, }, + }, + }, + .pw = { + .addr = ST_PRESS_LPS22HB_PW_ADDR, + .mask = ST_PRESS_LPS22HB_PW_MASK, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .fs_avl = { + [0] = { + .num = ST_PRESS_FS_AVL_1260MB, + .gain = ST_PRESS_KPASCAL_NANO_SCALE, + }, + }, + }, + .bdu = { + .addr = ST_PRESS_LPS22HB_BDU_ADDR, + .mask = ST_PRESS_LPS22HB_BDU_MASK, + }, + .drdy_irq = { + .addr = ST_PRESS_LPS22HB_DRDY_IRQ_ADDR, + .mask_int1 = ST_PRESS_LPS22HB_DRDY_IRQ_INT1_MASK, + .mask_int2 = ST_PRESS_LPS22HB_DRDY_IRQ_INT2_MASK, + .addr_ihl = ST_PRESS_LPS22HB_IHL_IRQ_ADDR, + .mask_ihl = ST_PRESS_LPS22HB_IHL_IRQ_MASK, + }, + .multi_read_bit = ST_PRESS_LPS22HB_MULTIREAD_BIT, + }, }; static int st_press_write_raw(struct iio_dev *indio_dev, @@ -454,10 +540,9 @@ int st_press_common_probe(struct iio_dev *indio_dev) indio_dev->channels = press_data->sensor_settings->ch; indio_dev->num_channels = press_data->sensor_settings->num_ch; - if (press_data->sensor_settings->fs.addr != 0) - press_data->current_fullscale = - (struct st_sensor_fullscale_avl *) - &press_data->sensor_settings->fs.fs_avl[0]; + press_data->current_fullscale = + (struct st_sensor_fullscale_avl *) + &press_data->sensor_settings->fs.fs_avl[0]; press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz; diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 8fcf9766eaec..ed18701c68c9 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -32,6 +32,10 @@ static const struct of_device_id st_press_of_match[] = { .compatible = "st,lps331ap-press", .data = LPS331AP_PRESS_DEV_NAME, }, + { + .compatible = "st,lps22hb-press", + .data = LPS22HB_PRESS_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_press_of_match); diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index 40c0692ff1de..550508025af1 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -50,6 +50,7 @@ static const struct spi_device_id st_press_id_table[] = { { LPS001WP_PRESS_DEV_NAME }, { LPS25H_PRESS_DEV_NAME }, { LPS331AP_PRESS_DEV_NAME }, + { LPS22HB_PRESS_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_press_id_table); -- cgit v1.3-14-g43fede From 4b9d2090a444d44f16788b9ad60180011d133f97 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Tue, 24 May 2016 21:29:19 -0700 Subject: iio: electricalconductivity: add IIO_ELECTRICALCONDUCTIVITY type Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++ drivers/iio/industrialio-core.c | 1 + include/uapi/linux/iio/types.h | 1 + 3 files changed, 9 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index df44998e7506..e7f590c6ef8e 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1565,3 +1565,10 @@ Description: * X is in the plane of the propellers, perpendicular to Y axis, and positive towards the starboard side of the UAV ; * Z is perpendicular to propellers plane and positive upwards. + +What: /sys/bus/iio/devices/iio:deviceX/in_electricalconductivity_raw +KernelVersion: 4.8 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no offset etc.) electric conductivity reading that + can be processed to siemens per meter. diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e6319a9346b2..2a85bd888619 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -80,6 +80,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_RESISTANCE] = "resistance", [IIO_PH] = "ph", [IIO_UVINDEX] = "uvindex", + [IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity", }; static const char * const iio_modifier_names[] = { diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index b0916fc72cce..22e5e589a274 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -39,6 +39,7 @@ enum iio_chan_type { IIO_RESISTANCE, IIO_PH, IIO_UVINDEX, + IIO_ELECTRICALCONDUCTIVITY, }; enum iio_modifier { -- cgit v1.3-14-g43fede From e8dd92bfbff2516f3e76bf08f38131c522454edd Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Tue, 24 May 2016 21:29:20 -0700 Subject: iio: chemical: atlas-ph-sensor: add EC feature Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- .../bindings/iio/chemical/atlas,ec-sm.txt | 22 ++++ drivers/iio/chemical/Kconfig | 8 +- drivers/iio/chemical/atlas-ph-sensor.c | 122 ++++++++++++++++++++- 3 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt b/Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt new file mode 100644 index 000000000000..2962bd9a2b3d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/atlas,ec-sm.txt @@ -0,0 +1,22 @@ +* Atlas Scientific EC-SM OEM sensor + +http://www.atlas-scientific.com/_files/_datasheets/_oem/EC_oem_datasheet.pdf + +Required properties: + + - compatible: must be "atlas,ec-sm" + - reg: the I2C address of the sensor + - interrupt-parent: should be the phandle for the interrupt controller + - interrupts: the sole interrupt generated by the device + + Refer to interrupt-controller/interrupts.txt for generic interrupt client + node bindings. + +Example: + +atlas@64 { + compatible = "atlas,ec-sm"; + reg = <0x64>; + interrupt-parent = <&gpio1>; + interrupts = <16 2>; +}; diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig index f73290f84c90..4bcc025e8c8a 100644 --- a/drivers/iio/chemical/Kconfig +++ b/drivers/iio/chemical/Kconfig @@ -5,15 +5,17 @@ menu "Chemical Sensors" config ATLAS_PH_SENSOR - tristate "Atlas Scientific OEM pH-SM sensor" + tristate "Atlas Scientific OEM SM sensors" depends on I2C select REGMAP_I2C select IIO_BUFFER select IIO_TRIGGERED_BUFFER select IRQ_WORK help - Say Y here to build I2C interface support for the Atlas - Scientific OEM pH-SM sensor. + Say Y here to build I2C interface support for the following + Atlas Scientific OEM SM sensors: + * pH SM sensor + * EC SM sensor To compile this driver as module, choose M here: the module will be called atlas-ph-sensor. diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c index e85477cb16fd..02e85db5d31f 100644 --- a/drivers/iio/chemical/atlas-ph-sensor.c +++ b/drivers/iio/chemical/atlas-ph-sensor.c @@ -50,13 +50,28 @@ #define ATLAS_REG_PH_CALIB_STATUS_MID BIT(1) #define ATLAS_REG_PH_CALIB_STATUS_HIGH BIT(2) +#define ATLAS_REG_EC_CALIB_STATUS 0x0f +#define ATLAS_REG_EC_CALIB_STATUS_MASK 0x0f +#define ATLAS_REG_EC_CALIB_STATUS_DRY BIT(0) +#define ATLAS_REG_EC_CALIB_STATUS_SINGLE BIT(1) +#define ATLAS_REG_EC_CALIB_STATUS_LOW BIT(2) +#define ATLAS_REG_EC_CALIB_STATUS_HIGH BIT(3) + #define ATLAS_REG_PH_TEMP_DATA 0x0e #define ATLAS_REG_PH_DATA 0x16 +#define ATLAS_REG_EC_PROBE 0x08 +#define ATLAS_REG_EC_TEMP_DATA 0x10 +#define ATLAS_REG_EC_DATA 0x18 +#define ATLAS_REG_TDS_DATA 0x1c +#define ATLAS_REG_PSS_DATA 0x20 + #define ATLAS_PH_INT_TIME_IN_US 450000 +#define ATLAS_EC_INT_TIME_IN_US 650000 enum { ATLAS_PH_SM, + ATLAS_EC_SM, }; struct atlas_data { @@ -66,12 +81,13 @@ struct atlas_data { struct regmap *regmap; struct irq_work work; - __be32 buffer[4]; /* 32-bit pH data + 32-bit pad + 64-bit timestamp */ + __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */ }; static const struct regmap_range atlas_volatile_ranges[] = { regmap_reg_range(ATLAS_REG_INT_CONTROL, ATLAS_REG_INT_CONTROL), regmap_reg_range(ATLAS_REG_PH_DATA, ATLAS_REG_PH_DATA + 4), + regmap_reg_range(ATLAS_REG_EC_DATA, ATLAS_REG_PSS_DATA + 4), }; static const struct regmap_access_table atlas_volatile_table = { @@ -86,7 +102,7 @@ static const struct regmap_config atlas_regmap_config = { .val_bits = 8, .volatile_table = &atlas_volatile_table, - .max_register = ATLAS_REG_PH_DATA + 4, + .max_register = ATLAS_REG_PSS_DATA + 4, .cache_type = REGCACHE_RBTREE, }; @@ -115,6 +131,50 @@ static const struct iio_chan_spec atlas_ph_channels[] = { }, }; +#define ATLAS_EC_CHANNEL(_idx, _addr) \ + {\ + .type = IIO_CONCENTRATION, \ + .indexed = 1, \ + .channel = _idx, \ + .address = _addr, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = _idx + 1, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 32, \ + .storagebits = 32, \ + .endianness = IIO_BE, \ + }, \ + } + +static const struct iio_chan_spec atlas_ec_channels[] = { + { + .type = IIO_ELECTRICALCONDUCTIVITY, + .address = ATLAS_REG_EC_DATA, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_BE, + }, + }, + ATLAS_EC_CHANNEL(0, ATLAS_REG_TDS_DATA), + ATLAS_EC_CHANNEL(1, ATLAS_REG_PSS_DATA), + IIO_CHAN_SOFT_TIMESTAMP(3), + { + .type = IIO_TEMP, + .address = ATLAS_REG_EC_TEMP_DATA, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .output = 1, + .scan_index = -1 + }, +}; + static int atlas_check_ph_calibration(struct atlas_data *data) { struct device *dev = &data->client->dev; @@ -142,6 +202,44 @@ static int atlas_check_ph_calibration(struct atlas_data *data) return 0; } +static int atlas_check_ec_calibration(struct atlas_data *data) +{ + struct device *dev = &data->client->dev; + int ret; + unsigned int val; + + ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &val, 2); + if (ret) + return ret; + + dev_info(dev, "probe set to K = %d.%.2d", be16_to_cpu(val) / 100, + be16_to_cpu(val) % 100); + + ret = regmap_read(data->regmap, ATLAS_REG_EC_CALIB_STATUS, &val); + if (ret) + return ret; + + if (!(val & ATLAS_REG_EC_CALIB_STATUS_MASK)) { + dev_warn(dev, "device has not been calibrated\n"); + return 0; + } + + if (!(val & ATLAS_REG_EC_CALIB_STATUS_DRY)) + dev_warn(dev, "device missing dry point calibration\n"); + + if (val & ATLAS_REG_EC_CALIB_STATUS_SINGLE) { + dev_warn(dev, "device using single point calibration\n"); + } else { + if (!(val & ATLAS_REG_EC_CALIB_STATUS_LOW)) + dev_warn(dev, "device missing low point calibration\n"); + + if (!(val & ATLAS_REG_EC_CALIB_STATUS_HIGH)) + dev_warn(dev, "device missing high point calibration\n"); + } + + return 0; +} + struct atlas_device { const struct iio_chan_spec *channels; int num_channels; @@ -159,6 +257,14 @@ static struct atlas_device atlas_devices[] = { .calibration = &atlas_check_ph_calibration, .delay = ATLAS_PH_INT_TIME_IN_US, }, + [ATLAS_EC_SM] = { + .channels = atlas_ec_channels, + .num_channels = 5, + .data_reg = ATLAS_REG_EC_DATA, + .calibration = &atlas_check_ec_calibration, + .delay = ATLAS_EC_INT_TIME_IN_US, + }, + }; static int atlas_set_powermode(struct atlas_data *data, int on) @@ -294,6 +400,8 @@ static int atlas_read_raw(struct iio_dev *indio_dev, (u8 *) ®, sizeof(reg)); break; case IIO_PH: + case IIO_CONCENTRATION: + case IIO_ELECTRICALCONDUCTIVITY: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) @@ -324,6 +432,14 @@ static int atlas_read_raw(struct iio_dev *indio_dev, *val = 1; /* 0.001 */ *val2 = 1000; break; + case IIO_ELECTRICALCONDUCTIVITY: + *val = 1; /* 0.00001 */ + *val = 100000; + break; + case IIO_CONCENTRATION: + *val = 0; /* 0.000000001 */ + *val2 = 1000; + return IIO_VAL_INT_PLUS_NANO; default: return -EINVAL; } @@ -358,12 +474,14 @@ static const struct iio_info atlas_info = { static const struct i2c_device_id atlas_id[] = { { "atlas-ph-sm", ATLAS_PH_SM}, + { "atlas-ec-sm", ATLAS_EC_SM}, {} }; MODULE_DEVICE_TABLE(i2c, atlas_id); static const struct of_device_id atlas_dt_ids[] = { { .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, }, + { .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, }, { } }; MODULE_DEVICE_TABLE(of, atlas_dt_ids); -- cgit v1.3-14-g43fede From 8d5b5d5ce58ee1b90110f4e358eefe3c3a6b08a2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2016 19:36:57 +0900 Subject: reset: add devm_reset_controller_register API Add a device managed API for reset_controller_register(). This helps in reducing code in .remove callbacks and sometimes dropping .remove callbacks entirely. Signed-off-by: Masahiro Yamada Acked-by: Laxman Dewangan Signed-off-by: Philipp Zabel --- Documentation/driver-model/devres.txt | 4 ++++ drivers/reset/core.c | 37 +++++++++++++++++++++++++++++++++++ include/linux/reset-controller.h | 4 ++++ 3 files changed, 45 insertions(+) (limited to 'Documentation') diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index c63eea0c1c8c..f5e522342ee5 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -352,6 +352,10 @@ REGULATOR devm_regulator_put() devm_regulator_register() +RESET + devm_reset_control_get() + devm_reset_controller_register() + SLAVE DMA ENGINE devm_acpi_dma_controller_register() diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 72b32bd15549..395dc9ce492e 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -93,6 +93,43 @@ void reset_controller_unregister(struct reset_controller_dev *rcdev) } EXPORT_SYMBOL_GPL(reset_controller_unregister); +static void devm_reset_controller_release(struct device *dev, void *res) +{ + reset_controller_unregister(*(struct reset_controller_dev **)res); +} + +/** + * devm_reset_controller_register - resource managed reset_controller_register() + * @dev: device that is registering this reset controller + * @rcdev: a pointer to the initialized reset controller device + * + * Managed reset_controller_register(). For reset controllers registered by + * this function, reset_controller_unregister() is automatically called on + * driver detach. See reset_controller_register() for more information. + */ +int devm_reset_controller_register(struct device *dev, + struct reset_controller_dev *rcdev) +{ + struct reset_controller_dev **rcdevp; + int ret; + + rcdevp = devres_alloc(devm_reset_controller_release, sizeof(*rcdevp), + GFP_KERNEL); + if (!rcdevp) + return -ENOMEM; + + ret = reset_controller_register(rcdev); + if (!ret) { + *rcdevp = rcdev; + devres_add(dev, rcdevp); + } else { + devres_free(rcdevp); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_reset_controller_register); + /** * reset_control_reset - reset the controlled device * @rstc: reset controller diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index b91ba932bbd4..db1fe6772ad5 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -53,4 +53,8 @@ struct reset_controller_dev { int reset_controller_register(struct reset_controller_dev *rcdev); void reset_controller_unregister(struct reset_controller_dev *rcdev); +struct device; +int devm_reset_controller_register(struct device *dev, + struct reset_controller_dev *rcdev); + #endif -- cgit v1.3-14-g43fede From aeb99c85c1c493bfe8a4f53b68af8e68fc1ed7bc Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 11 May 2016 09:34:22 +0200 Subject: dt-bindings: Add Oxford Semiconductor OXNAS pinctrl and gpio bindings Add pinctrl and gpio DT bindings for Oxford Semiconductor OXNAS SoC Family. This version supports the ARM926EJ-S based OX810SE SoC with 34 IO pins. Signed-off-by: Neil Armstrong Acked-by: Rob Herring Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio_oxnas.txt | 47 ++++++++++++++++++ .../devicetree/bindings/pinctrl/oxnas,pinctrl.txt | 57 ++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio_oxnas.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/gpio_oxnas.txt b/Documentation/devicetree/bindings/gpio/gpio_oxnas.txt new file mode 100644 index 000000000000..928ed4f43907 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_oxnas.txt @@ -0,0 +1,47 @@ +* Oxford Semiconductor OXNAS SoC GPIO Controller + +Please refer to gpio.txt for generic information regarding GPIO bindings. + +Required properties: + - compatible: "oxsemi,ox810se-gpio" + - reg: Base address and length for the device. + - interrupts: The port interrupt shared by all pins. + - gpio-controller: Marks the port as GPIO controller. + - #gpio-cells: Two. The first cell is the pin number and + the second cell is used to specify the gpio polarity as defined in + defined in : + 0 = GPIO_ACTIVE_HIGH + 1 = GPIO_ACTIVE_LOW + - interrupt-controller: Marks the device node as an interrupt controller. + - #interrupt-cells: Two. The first cell is the GPIO number and second cell + is used to specify the trigger type as defined in + : + IRQ_TYPE_EDGE_RISING + IRQ_TYPE_EDGE_FALLING + IRQ_TYPE_EDGE_BOTH + - gpio-ranges: Interaction with the PINCTRL subsystem, it also specifies the + gpio base and count, should be in the format of numeric-gpio-range as + specified in the gpio.txt file. + +Example: + +gpio0: gpio@0 { + compatible = "oxsemi,ox810se-gpio"; + reg = <0x000000 0x100000>; + interrupts = <21>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&pinctrl 0 0 32>; +}; + +keys { + ... + + button-esc { + label = "ESC"; + linux,code = <1>; + gpios = <&gpio0 12 0>; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt new file mode 100644 index 000000000000..d6074321f730 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt @@ -0,0 +1,57 @@ +* Oxford Semiconductor OXNAS SoC Family Pin Controller + +Please refer to pinctrl-bindings.txt, ../gpio/gpio.txt, and +../interrupt-controller/interrupts.txt for generic information regarding +pin controller, GPIO, and interrupt bindings. + +OXNAS 'pin configuration node' is a node of a group of pins which can be +used for a specific device or function. This node represents configurations of +pins, optional function, and optional mux related configuration. + +Required properties for pin controller node: + - compatible: "oxsemi,ox810se-pinctrl" + - oxsemi,sys-ctrl: a phandle to the system controller syscon node + +Required properties for pin configuration sub-nodes: + - pins: List of pins to which the configuration applies. + +Optional properties for pin configuration sub-nodes: +---------------------------------------------------- + - function: Mux function for the specified pins. + - bias-pull-up: Enable weak pull-up. + +Example: + +pinctrl: pinctrl { + compatible = "oxsemi,ox810se-pinctrl"; + + /* Regmap for sys registers */ + oxsemi,sys-ctrl = <&sys>; + + pinctrl_uart2: pinctrl_uart2 { + uart2a { + pins = "gpio31"; + function = "fct3"; + }; + uart2b { + pins = "gpio32"; + function = "fct3"; + }; + }; +}; + +uart2: serial@900000 { + compatible = "ns16550a"; + reg = <0x900000 0x100000>; + clocks = <&sysclk>; + interrupts = <29>; + reg-shift = <0>; + fifo-size = <16>; + reg-io-width = <1>; + current-speed = <115200>; + no-loopback-test; + status = "disabled"; + resets = <&reset 22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; +}; -- cgit v1.3-14-g43fede From 7916c0c3c65eae12ce7528031e0c015c85b034c9 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 13 May 2016 10:49:13 +0530 Subject: pinctrl: add DT binding doc for pincontrol of PMIC max77620/max20024 Maxim Semiconductor's PMIC MAX77620/MAX20024 has 8 GPIO pins which act as GPIO as well as special function mode. Add DT binding document to configure pins in function mode as well as pin configuration parameters. Signed-off-by: Laxman Dewangan Acked-by: Rob Herring Signed-off-by: Linus Walleij --- .../bindings/pinctrl/pinctrl-max77620.txt | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt new file mode 100644 index 000000000000..ad4fce3552bb --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt @@ -0,0 +1,127 @@ +Pincontrol driver for MAX77620 Power management IC from Maxim Semiconductor. + +Device has 8 GPIO pins which can be configured as GPIO as well as the +special IO functions. + +Please refer file +for details of the common pinctrl bindings used by client devices, +including the meaning of the phrase "pin configuration node". + +Optional Pinmux properties: +-------------------------- +Following properties are required if default setting of pins are required +at boot. +- pinctrl-names: A pinctrl state named per . +- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per + . + +The pin configurations are defined as child of the pinctrl states node. Each +sub-node have following properties: + +Required properties: +------------------ +- pins: List of pins. Valid values of pins properties are: + gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7. + +Optional properties: +------------------- +Following are optional properties defined as pinmux DT binding document +. Absence of properties will leave the configuration +on default. + function, + drive-push-pull, + drive-open-drain, + bias-pull-up, + bias-pull-down. + +Valid values for function properties are: + gpio, lpm-control-in, fps-out, 32k-out, sd0-dvs-in, sd1-dvs-in, + reference-out + +Theres is also customised properties for the GPIO1, GPIO2 and GPIO3. These +customised properties are required to configure FPS configuration parameters +of these GPIOs. Please refer for more +detail of Flexible Power Sequence (FPS). + +- maxim,active-fps-source: FPS source for the GPIOs to get + enabled/disabled when system is in + active state. Valid values are: + - MAX77620_FPS_SRC_0, + FPS source is FPS0. + - MAX77620_FPS_SRC_1, + FPS source is FPS1 + - MAX77620_FPS_SRC_2 and + FPS source is FPS2 + - MAX77620_FPS_SRC_NONE. + GPIO is not controlled + by FPS events and it gets + enabled/disabled by register + access. + Absence of this property will leave + the FPS configuration register for that + GPIO to default configuration. + +- maxim,active-fps-power-up-slot: Sequencing event slot number on which + the GPIO get enabled when + master FPS input event set to HIGH. + Valid values are 0 to 7. + This is applicable if FPS source is + selected as FPS0, FPS1 or FPS2. + +- maxim,active-fps-power-down-slot: Sequencing event slot number on which + the GPIO get disabled when master + FPS input event set to LOW. + Valid values are 0 to 7. + This is applicable if FPS source is + selected as FPS0, FPS1 or FPS2. + +- maxim,suspend-fps-source: This is same as property + "maxim,active-fps-source" but value + get configured when system enters in + to suspend state. + +- maxim,suspend-fps-power-up-slot: This is same as property + "maxim,active-fps-power-up-slot" but + this value get configured into FPS + configuration register when system + enters into suspend. + This is applicable if suspend state + FPS source is selected as FPS0, FPS1 or + +- maxim,suspend-fps-power-down-slot: This is same as property + "maxim,active-fps-power-down-slot" but + this value get configured into FPS + configuration register when system + enters into suspend. + This is applicable if suspend state + FPS source is selected as FPS0, FPS1 or + FPS2. + +Example: +-------- +#include +... +max77620@3c { + + pinctrl-names = "default"; + pinctrl-0 = <&spmic_default>; + + spmic_default: pinmux@0 { + pin_gpio0 { + pins = "gpio0"; + function = "gpio"; + }; + + pin_gpio1 { + pins = "gpio1"; + function = "fps-out"; + maxim,active-fps-source = ; + }; + + pin_gpio2 { + pins = "gpio2"; + function = "fps-out"; + maxim,active-fps-source = ; + }; + }; +}; -- cgit v1.3-14-g43fede From cabfeaa67843bf8ddda819a6129e20472053310a Mon Sep 17 00:00:00 2001 From: "Cooper Jr., Franklin" Date: Wed, 4 May 2016 13:34:44 -0500 Subject: ARM: OMAP2+: Update GPMC and NAND DT binding documentation Add additional details to the GPMC NAND documentation to clarify what is needed to enable NAND DMA prefetch. Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Signed-off-by: Boris Brezillon --- Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt | 7 ++++++- Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt index 21055e210234..c1359f4d48d7 100644 --- a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt +++ b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt @@ -46,6 +46,10 @@ Required properties: 0 maps to GPMC_WAIT0 pin. - gpio-cells: Must be set to 2 +Required properties when using NAND prefetch dma: + - dmas GPMC NAND prefetch dma channel + - dma-names Must be set to "rxtx" + Timing properties for child nodes. All are optional and default to 0. - gpmc,sync-clk-ps: Minimum clock period for synchronous mode, in picoseconds @@ -137,7 +141,8 @@ Example for an AM33xx board: ti,hwmods = "gpmc"; reg = <0x50000000 0x2000>; interrupts = <100>; - + dmas = <&edma 52 0>; + dma-names = "rxtx"; gpmc,num-cs = <8>; gpmc,num-waitpins = <2>; #address-cells = <2>; diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index 3ee7e202657c..174f68c26c1b 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -39,7 +39,7 @@ Optional properties: "prefetch-polled" Prefetch polled mode (default) "polled" Polled mode, without prefetch - "prefetch-dma" Prefetch enabled sDMA mode + "prefetch-dma" Prefetch enabled DMA mode "prefetch-irq" Prefetch enabled irq mode - elm_id: use "ti,elm-id" instead -- cgit v1.3-14-g43fede From 0645de5a4c22638170f6e0bb31a0b1c9f52daf93 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 30 May 2016 11:10:49 +0200 Subject: drm/doc: Unify KMS Locking docs Signed-off-by: Daniel Vetter Acked-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1464599449-12509-1-git-send-email-daniel.vetter@ffwll.ch --- Documentation/DocBook/gpu.tmpl | 16 ---------------- drivers/gpu/drm/drm_modeset_lock.c | 11 +++++++++-- 2 files changed, 9 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 90dbdb5087c4..221a4929ca59 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1092,22 +1092,6 @@ int max_width, max_height; operation. - - Locking - - Beside some lookup structures with their own locking (which is hidden - behind the interface functions) most of the modeset state is protected - by the dev-<mode_config.lock mutex and additionally - per-crtc locks to allow cursor updates, pageflips and similar operations - to occur concurrently with background tasks like output detection. - Operations which cross domains like a full modeset always grab all - locks. Drivers there need to protect resources shared between crtcs with - additional locking. They also need to be careful to always grab the - relevant crtc locks if a modset functions touches crtc state, e.g. for - load detection (which does only grab the mode_config.lock - to allow concurrent screen updates on live crtcs). - - diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index e3a4adf03e7b..f33ebe638a28 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -30,12 +30,12 @@ * * As KMS moves toward more fine grained locking, and atomic ioctl where * userspace can indirectly control locking order, it becomes necessary - * to use ww_mutex and acquire-contexts to avoid deadlocks. But because + * to use &ww_mutex and acquire-contexts to avoid deadlocks. But because * the locking is more distributed around the driver code, we want a bit * of extra utility/tracking out of our acquire-ctx. This is provided * by drm_modeset_lock / drm_modeset_acquire_ctx. * - * For basic principles of ww_mutex, see: Documentation/locking/ww-mutex-design.txt + * For basic principles of &ww_mutex, see: Documentation/locking/ww-mutex-design.txt * * The basic usage pattern is to: * @@ -51,6 +51,13 @@ * ... do stuff ... * drm_modeset_drop_locks(&ctx); * drm_modeset_acquire_fini(&ctx); + * + * On top of of these per-object locks using &ww_mutex there's also an overall + * dev->mode_config.lock, for protecting everything else. Mostly this means + * probe state of connectors, and preventing hotplug add/removal of connectors. + * + * Finally there's a bunch of dedicated locks to protect drm core internal + * lists and lookup data structures. */ /** -- cgit v1.3-14-g43fede From 22cba31bae9dc357622f09d22b82ca5a112b4fde Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 May 2016 15:14:05 +0300 Subject: Documentation/sphinx: add basic working Sphinx configuration and build Add basic configuration and makefile to build documentation from any .rst files under Documentation using Sphinx. For starters, there's just the placeholder index.rst. At the top level Makefile, hook Sphinx documentation targets alongside (but independent of) the DocBook toolchain, having both be run on the various 'make *docs' targets. All Sphinx processing is placed into Documentation/Makefile.sphinx. Both that and the Documentation/DocBook/Makefile are now expected to handle all the documentation targets, explicitly ignoring them if they're not relevant for that particular toolchain. The changes to the existing DocBook Makefile are kept minimal. There is graceful handling of missing Sphinx and rst2pdf (which is needed for pdf output) by checking for the tool and python module, respectively, with informative messages to the user. If the Read the Docs theme (sphinx_rtd_theme) is available, use it, but otherwise gracefully fall back to the Sphinx default theme, with an informative message to the user, and slightly less pretty HTML output. Sphinx can now handle htmldocs, pdfdocs (if rst2pdf is available), epubdocs and xmldocs targets. The output documents are written into per output type subdirectories under Documentation/output. Finally, you can pass options to sphinx-build using the SPHINXBUILD make variable. For example, 'make SPHINXOPTS=-v htmldocs' for more verbose output from Sphinx. This is based on the original work by Jonathan Corbet, but he probably wouldn't recognize this as his own anymore. Signed-off-by: Jani Nikula --- Documentation/DocBook/Makefile | 7 +- Documentation/Makefile.sphinx | 61 +++++++ Documentation/conf.py | 387 +++++++++++++++++++++++++++++++++++++++++ Documentation/index.rst | 23 +++ Makefile | 5 +- 5 files changed, 478 insertions(+), 5 deletions(-) create mode 100644 Documentation/Makefile.sphinx create mode 100644 Documentation/conf.py create mode 100644 Documentation/index.rst (limited to 'Documentation') diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index d70f9b68174e..e0c7e1e0590b 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -33,10 +33,6 @@ PDF_METHOD = $(prefer-db2x) PS_METHOD = $(prefer-db2x) -### -# The targets that may be used. -PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs - targets += $(DOCBOOKS) BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) xmldocs: $(BOOKS) @@ -63,6 +59,9 @@ installmandocs: mandocs sort -k 2 -k 1 | uniq -f 1 | sed -e 's: :/:' | \ xargs install -m 644 -t /usr/local/man/man9/ +# no-op for the DocBook toolchain +epubdocs: + ### #External programs used KERNELDOCXMLREF = $(srctree)/scripts/kernel-doc-xml-ref diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx new file mode 100644 index 000000000000..25a7970bfe5c --- /dev/null +++ b/Documentation/Makefile.sphinx @@ -0,0 +1,61 @@ +# -*- makefile -*- +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXBUILD = sphinx-build +SPHINXOPTS = +PAPER = +BUILDDIR = $(obj)/output + +# User-friendly check for sphinx-build +HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi) + +ifeq ($(HAVE_SPHINX),0) + +.DEFAULT: + $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) + @echo " SKIP Sphinx $@ target." + +else # HAVE_SPHINX + +# User-friendly check for rst2pdf +HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/dev/null 2>&1; then echo 1; else echo 0; fi) + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +quiet_cmd_sphinx = SPHINX $@ + cmd_sphinx = $(SPHINXBUILD) -b $2 $(ALLSPHINXOPTS) $(BUILDDIR)/$2 + +htmldocs: + $(call cmd,sphinx,html) + +pdfdocs: +ifeq ($(HAVE_RST2PDF),0) + $(warning The Python 'rst2pdf' module was not found. Make sure you have the module installed to produce PDF output.) + @echo " SKIP Sphinx $@ target." +else # HAVE_RST2PDF + $(call cmd,sphinx,pdf) +endif # HAVE_RST2PDF + +epubdocs: + $(call cmd,sphinx,epub) + +xmldocs: + $(call cmd,sphinx,xml) + +# no-ops for the Sphinx toolchain +sgmldocs: +psdocs: +mandocs: +installmandocs: + +cleandocs: + $(Q)rm -rf $(BUILDDIR) + +endif # HAVE_SPHINX diff --git a/Documentation/conf.py b/Documentation/conf.py new file mode 100644 index 000000000000..0f0e20757bb1 --- /dev/null +++ b/Documentation/conf.py @@ -0,0 +1,387 @@ +# -*- coding: utf-8 -*- +# +# The Linux Kernel documentation build configuration file, created by +# sphinx-quickstart on Fri Feb 12 13:51:46 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Gracefully handle missing rst2pdf. +try: + import rst2pdf + extensions += ['rst2pdf.pdfbuilder'] +except ImportError: + pass + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'The Linux Kernel' +copyright = '2016, The kernel development community' +author = 'The kernel development community' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '4.5' +# The full version, including alpha/beta/rc tags. +release = '4.5' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['output'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +primary_domain = 'C' +highlight_language = 'C' + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. + +# The Read the Docs theme is available from +# - https://github.com/snide/sphinx_rtd_theme +# - https://pypi.python.org/pypi/sphinx_rtd_theme +# - python-sphinx-rtd-theme package (on Debian) +try: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +except ImportError: + sys.stderr.write('Warning: The Sphinx \'sphinx_rtd_theme\' HTML theme was not found. Make sure you have the theme installed to produce pretty HTML output. Falling back to the default theme.\n') + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'TheLinuxKerneldoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'TheLinuxKernel.tex', 'The Linux Kernel Documentation', + 'The kernel development community', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'thelinuxkernel', 'The Linux Kernel Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'TheLinuxKernel', 'The Linux Kernel Documentation', + author, 'TheLinuxKernel', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The basename for the epub file. It defaults to the project name. +#epub_basename = project + +# The HTML theme for the epub output. Since the default themes are not +# optimized for small screen space, using the same theme for HTML and epub +# output is usually not wise. This defaults to 'epub', a theme designed to save +# visual space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or 'en' if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files that should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the Pillow. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True + +#======= +# rst2pdf +# +# Grouping the document tree into PDF files. List of tuples +# (source start file, target name, title, author, options). +# +# See the Sphinx chapter of http://ralsina.me/static/manual.pdf +# +# FIXME: Do not add the index file here; the result will be too big. Adding +# multiple PDF files here actually tries to get the cross-referencing right +# *between* PDF files. +pdf_documents = [ + ('index', u'Kernel', u'Kernel', u'J. Random Bozo'), +] diff --git a/Documentation/index.rst b/Documentation/index.rst new file mode 100644 index 000000000000..71a276f34c7f --- /dev/null +++ b/Documentation/index.rst @@ -0,0 +1,23 @@ +.. The Linux Kernel documentation master file, created by + sphinx-quickstart on Fri Feb 12 13:51:46 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to The Linux Kernel's documentation! +============================================ + +Nothing for you to see here *yet*. Please move along. + +Contents: + +.. toctree:: + :maxdepth: 2 + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/Makefile b/Makefile index 0f70de63cfdb..8908a51b895a 100644 --- a/Makefile +++ b/Makefile @@ -1412,8 +1412,11 @@ $(help-board-dirs): help-%: # Documentation targets # --------------------------------------------------------------------------- -%docs: scripts_basic FORCE +DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs +PHONY += $(DOC_TARGETS) +$(DOC_TARGETS): scripts_basic FORCE $(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype + $(Q)$(MAKE) $(build)=Documentation -f $(srctree)/Documentation/Makefile.sphinx $@ $(Q)$(MAKE) $(build)=Documentation/DocBook $@ else # KBUILD_EXTMOD -- cgit v1.3-14-g43fede From 81cd318102aedee64d3bd38d2e04ea333569abfd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 May 2016 20:53:23 +0300 Subject: Documentation: add .gitignore The Sphinx output directory is generated. Signed-off-by: Jani Nikula --- Documentation/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 Documentation/.gitignore (limited to 'Documentation') diff --git a/Documentation/.gitignore b/Documentation/.gitignore new file mode 100644 index 000000000000..53752db253e3 --- /dev/null +++ b/Documentation/.gitignore @@ -0,0 +1 @@ +output -- cgit v1.3-14-g43fede From c56de1db54dfbbdfc02a500388952af16e3a9368 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 May 2016 23:30:30 +0300 Subject: Documentation/sphinx: add Sphinx kernel-doc directive extension Add an extension to handle kernel-doc directives, to call kernel-doc according to the arguments and parameters given to the reStructuredText directive. The syntax for the kernel-doc directive is: .. kernel-doc:: FILENAME :export: :internal: :functions: FUNCTION [FUNCTION ...] :doc: SECTION TITLE Of the directive options export, internal, functions, and doc, currently only one option may be given at a time. The FILENAME is relative from the kernel source tree root. The extension notifies Sphinx about the document dependency on FILENAME, causing the document to be rebuilt when the file has been changed. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Documentation/sphinx/kernel-doc.py (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py new file mode 100644 index 000000000000..87a1332fe934 --- /dev/null +++ b/Documentation/sphinx/kernel-doc.py @@ -0,0 +1,102 @@ +# coding=utf-8 +# +# Copyright © 2016 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# Authors: +# Jani Nikula + +import os +import subprocess +import sys + +from docutils import nodes, statemachine +from docutils.parsers.rst import directives +from sphinx.util.compat import Directive + +class KernelDocDirective(Directive): + """Extract kernel-doc comments from the specified file""" + required_argument = 1 + optional_arguments = 4 + option_spec = { + 'doc': directives.unchanged_required, + 'functions': directives.unchanged_required, + 'export': directives.flag, + 'internal': directives.flag, + } + has_content = False + + def run(self): + env = self.state.document.settings.env + cmd = [env.config.kerneldoc_bin, '-rst'] + + filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] + + # Tell sphinx of the dependency + env.note_dependency(os.path.abspath(filename)) + + tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) + source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) + + # FIXME: make this nicer and more robust against errors + if 'export' in self.options: + cmd += ['-export'] + elif 'internal' in self.options: + cmd += ['-internal'] + elif 'doc' in self.options: + cmd += ['-function', str(self.options.get('doc'))] + elif 'functions' in self.options: + for f in str(self.options.get('functions')).split(' '): + cmd += ['-function', f] + + cmd += [filename] + + try: + env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) + + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + out, err = p.communicate() + + # assume the kernel sources are utf-8 + out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') + + if p.returncode != 0: + sys.stderr.write(err) + + env.app.warn('kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) + return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] + elif env.config.kerneldoc_verbosity > 0: + sys.stderr.write(err) + + lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) + self.state_machine.insert_input(lines, source) + return [] + except Exception as e: + env.app.warn('kernel-doc \'%s\' processing failed with: %s' % + (" ".join(cmd), str(e))) + return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] + +def setup(app): + app.add_config_value('kerneldoc_bin', None, 'env') + app.add_config_value('kerneldoc_srctree', None, 'env') + app.add_config_value('kerneldoc_verbosity', 1, 'env') + + app.add_directive('kernel-doc', KernelDocDirective) -- cgit v1.3-14-g43fede From 24dcdeb28b55afafa9cdf6acedd78cf1aa8f8428 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 May 2016 11:51:47 +0300 Subject: Documentation/sphinx: configure the kernel-doc extension Tell Sphinx where to find the extension, and pass on the kernel src tree and kernel-doc paths to the extension. With this, any .rst files under Documentation may contain the kernel-doc rst directive to include kernel-doc documentation from any source file. While building, it may be handy to pass kernel-doc extension configuration on the command line. For example, 'make SPHINXOPTS="-D kerneldoc_verbosity=0" htmldocs' silences all stderr output from kernel-doc when the kernel-doc exit code is 0. (The stderr will be logged unconditionally when the exit code is non-zero.) Signed-off-by: Jani Nikula --- Documentation/Makefile.sphinx | 4 +++- Documentation/conf.py | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index 25a7970bfe5c..8a662be9bd87 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -25,7 +25,9 @@ HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/dev/null 2>&1; then echo # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) +KERNELDOC = $(srctree)/scripts/kernel-doc +KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC) +ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . diff --git a/Documentation/conf.py b/Documentation/conf.py index 0f0e20757bb1..8b72577f38f5 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -18,7 +18,7 @@ import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('sphinx')) # -- General configuration ------------------------------------------------ @@ -28,7 +28,7 @@ import os # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +extensions = ['kernel-doc'] # Gracefully handle missing rst2pdf. try: @@ -385,3 +385,9 @@ epub_exclude_files = ['search.html'] pdf_documents = [ ('index', u'Kernel', u'Kernel', u'J. Random Bozo'), ] + +# kernel-doc extension configuration for running Sphinx directly (e.g. by Read +# the Docs). In a normal build, these are supplied from the Makefile via command +# line arguments. +kerneldoc_bin = '../scripts/kernel-doc' +kerneldoc_srctree = '..' -- cgit v1.3-14-g43fede From c13ce448c8532965eb4e1115e78cb5b8ff8261a3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 28 May 2016 15:25:41 +0300 Subject: Documentation/sphinx: set version and release properly Read the version and release from the top level Makefile (for use when Sphinx is invoked directly, by e.g. Read the Docs), but override them via Sphinx command line arguments in a normal documentation build. Signed-off-by: Jani Nikula --- Documentation/Makefile.sphinx | 2 +- Documentation/conf.py | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index 8a662be9bd87..addf32309bc3 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -27,7 +27,7 @@ PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter KERNELDOC = $(srctree)/scripts/kernel-doc KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC) -ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) +ALLSPHINXOPTS = -D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . diff --git a/Documentation/conf.py b/Documentation/conf.py index 8b72577f38f5..6cc41a0555a3 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -60,10 +60,31 @@ author = 'The kernel development community' # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. -version = '4.5' -# The full version, including alpha/beta/rc tags. -release = '4.5' +# In a normal build, version and release are are set to KERNELVERSION and +# KERNELRELEASE, respectively, from the Makefile via Sphinx command line +# arguments. +# +# The following code tries to extract the information by reading the Makefile, +# when Sphinx is run directly (e.g. by Read the Docs). +try: + makefile_version = None + makefile_patchlevel = None + for line in open('../Makefile'): + key, val = [x.strip() for x in line.split('=', 2)] + if key == 'VERSION': + makefile_version = val + elif key == 'PATCHLEVEL': + makefile_patchlevel = val + if makefile_version and makefile_patchlevel: + break +except: + pass +finally: + if makefile_version and makefile_patchlevel: + version = release = makefile_version + '.' + makefile_patchlevel + else: + sys.stderr.write('Warning: Could not extract kernel version\n') + version = release = "unknown version" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit v1.3-14-g43fede From 89a66d76109935aad387a5058f120aeb8246ae40 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 6 Mar 2016 20:29:31 -0700 Subject: sphinx: cheesy script to convert .tmpl files This script uses pandoc to convert existing DocBook template files to RST templates. A couple of sed scripts are need to massage things both before and after the conversion, but the result is then usable with no hand editing. [Jani: Change usage to tmplcvt . Fix escaping for docproc directives. Add support the new kernel-doc extension.] Signed-off-by: Jonathan Corbet Signed-off-by: Jani Nikula --- Documentation/sphinx/convert_template.sed | 14 ++++++++++++++ Documentation/sphinx/post_convert.sed | 19 +++++++++++++++++++ Documentation/sphinx/tmplcvt | 19 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 Documentation/sphinx/convert_template.sed create mode 100644 Documentation/sphinx/post_convert.sed create mode 100755 Documentation/sphinx/tmplcvt (limited to 'Documentation') diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed new file mode 100644 index 000000000000..d53bb8220a26 --- /dev/null +++ b/Documentation/sphinx/convert_template.sed @@ -0,0 +1,14 @@ +# +# Pandoc doesn't grok or , so convert them +# ahead of time. +# +# Use "$bq" instead of "`" so that pandoc won't mess with it. +# +s%\([^<(]\+\)()%:c:func:$bq\1$bq%g +s%\([^<(]\+\)%:c:func:$bq\1$bq%g +s%struct *\([^<]\+\)%:ref:$bqstruct \1$bq%g +s%\([^<]\+\)%:ref:$bqstruct \1$bq%g +# +# Wrap docproc directives in para and code blocks. +# +s%^\(!.*\)$%DOCPROC: \1% diff --git a/Documentation/sphinx/post_convert.sed b/Documentation/sphinx/post_convert.sed new file mode 100644 index 000000000000..ce17049f6a8e --- /dev/null +++ b/Documentation/sphinx/post_convert.sed @@ -0,0 +1,19 @@ +# +# pandoc thinks that both "_" needs to be escaped. Remove the extra +# backslashes. Also put in proper backquotes now that pandoc won't quote +# them. +# +s/$bq/`/g +s/\\_/_/g +# +# Unwrap docproc directives. +# +s/^``DOCPROC: !E\(.*\)``$/.. kernel-doc:: \1\n :export:/ +s/^``DOCPROC: !I\(.*\)``$/.. kernel-doc:: \1\n :internal:/ +s/^``DOCPROC: !F\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :functions: \2/ +s/^``DOCPROC: !P\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :doc: \2/ +s/^``DOCPROC: \(!.*\)``$/.. WARNING: DOCPROC directive not supported: \1/ +# +# Trim trailing whitespace. +# +s/[[:space:]]*$// diff --git a/Documentation/sphinx/tmplcvt b/Documentation/sphinx/tmplcvt new file mode 100755 index 000000000000..909a73065e0a --- /dev/null +++ b/Documentation/sphinx/tmplcvt @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Convert a template file into something like RST +# +# fix +# feed to pandoc +# fix \_ +# title line? +# + +in=$1 +rst=$2 +tmp=$rst.tmp + +cp $in $tmp +sed --in-place -f convert_template.sed $tmp +pandoc -s -S -f docbook -t rst -o $rst $tmp +sed --in-place -f post_convert.sed $rst +rm $tmp -- cgit v1.3-14-g43fede From 2e83ecb834ca923806fd58fab17d9f405767e1d9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 10:15:18 +0300 Subject: sphinx: update docbook->rst conversion script match C domain spec Function references should include the parens (), struct references should not include "struct". Signed-off-by: Jani Nikula --- Documentation/sphinx/convert_template.sed | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed index d53bb8220a26..0553eabeac79 100644 --- a/Documentation/sphinx/convert_template.sed +++ b/Documentation/sphinx/convert_template.sed @@ -4,10 +4,10 @@ # # Use "$bq" instead of "`" so that pandoc won't mess with it. # -s%\([^<(]\+\)()%:c:func:$bq\1$bq%g -s%\([^<(]\+\)%:c:func:$bq\1$bq%g -s%struct *\([^<]\+\)%:ref:$bqstruct \1$bq%g -s%\([^<]\+\)%:ref:$bqstruct \1$bq%g +s%\([^<(]\+\)()%:c:func:$bq\1()$bq%g +s%\([^<(]\+\)%:c:func:$bq\1()$bq%g +s%struct *\([^<]\+\)%:c:type:$bq\1$bq%g +s%\([^<]\+\)%:c:type:$bq\1$bq%g # # Wrap docproc directives in para and code blocks. # -- cgit v1.3-14-g43fede From 30ca7aaf279944da930b587b05d9b325ec7f821d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 10:40:17 +0300 Subject: Documentation/sphinx: nicer referencing of struct in docbook->rst conversion Add "struct" in the label of the reference. Signed-off-by: Jani Nikula --- Documentation/sphinx/convert_template.sed | 10 +++++++--- Documentation/sphinx/post_convert.sed | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed index 0553eabeac79..c1503fcca4ec 100644 --- a/Documentation/sphinx/convert_template.sed +++ b/Documentation/sphinx/convert_template.sed @@ -2,12 +2,16 @@ # Pandoc doesn't grok or , so convert them # ahead of time. # -# Use "$bq" instead of "`" so that pandoc won't mess with it. +# Use the following escapes to pass through pandoc: +# $bq = "`" +# $lt = "<" +# $gt = ">" # s%\([^<(]\+\)()%:c:func:$bq\1()$bq%g s%\([^<(]\+\)%:c:func:$bq\1()$bq%g -s%struct *\([^<]\+\)%:c:type:$bq\1$bq%g -s%\([^<]\+\)%:c:type:$bq\1$bq%g +s%struct *\([^<]\+\)%:c:type:$bqstruct \1 $lt\1$gt$bq%g +s%struct \([^<]\+\)%:c:type:$bqstruct \1 $lt\1$gt$bq%g +s%\([^<]\+\)%:c:type:$bqstruct \1 $lt\1$gt$bq%g # # Wrap docproc directives in para and code blocks. # diff --git a/Documentation/sphinx/post_convert.sed b/Documentation/sphinx/post_convert.sed index ce17049f6a8e..392770bac53b 100644 --- a/Documentation/sphinx/post_convert.sed +++ b/Documentation/sphinx/post_convert.sed @@ -1,9 +1,13 @@ # -# pandoc thinks that both "_" needs to be escaped. Remove the extra -# backslashes. Also put in proper backquotes now that pandoc won't quote -# them. +# Unescape. # s/$bq/`/g +s/$lt//g +# +# pandoc thinks that both "_" needs to be escaped. Remove the extra +# backslashes. +# s/\\_/_/g # # Unwrap docproc directives. -- cgit v1.3-14-g43fede From de9b1214c04f45949c9f692e447328a1058a41ac Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Wed, 25 May 2016 12:38:34 -0700 Subject: ASoC: cs53l30: Add codec driver support for Cirrus CS53L30 CS53L30 is a Quad-Channel ADC from Cirrus Logic with an I2S/TDM DAI. So this patch adds a codec driver for CS53L30 that includes 4-channel 24-bit recording and TDM mode supports. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/cs53l30.txt | 40 + sound/soc/codecs/Kconfig | 6 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/cs53l30.c | 1097 ++++++++++++++++++++ sound/soc/codecs/cs53l30.h | 458 ++++++++ 5 files changed, 1603 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/cs53l30.txt create mode 100644 sound/soc/codecs/cs53l30.c create mode 100644 sound/soc/codecs/cs53l30.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/cs53l30.txt b/Documentation/devicetree/bindings/sound/cs53l30.txt new file mode 100644 index 000000000000..18d6b99e0a2d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs53l30.txt @@ -0,0 +1,40 @@ +CS53L30 audio CODEC + +Required properties: + + - compatible : "cirrus,cs53l30" + + - reg : the I2C address of the device + + - VA-supply, VP-supply : power supplies for the device, + as covered in Documentation/devicetree/bindings/regulator/regulator.txt. + +Optional properties: + + - reset-gpios : a GPIO spec for the reset pin. + + - cirrus,micbias-lvl : Set the output voltage level on the MICBIAS Pin. + 0 = Hi-Z + 1 = 1.80 V + 2 = 2.75 V + + - cirrus,use-sdout2 : This is a boolean property. If present, it indicates + the hardware design connects both SDOUT1 and SDOUT2 + pins to output data. Otherwise, it indicates that + only SDOUT1 is connected for data output. + * CS53l30 supports 4-channel data output in the same + * frame using two different ways: + * 1) Normal I2S mode on two data pins -- each SDOUT + * carries 2-channel data in the same time. + * 2) TDM mode on one signle data pin -- SDOUT1 carries + * 4-channel data per frame. + +Example: + +codec: cs53l30@48 { + compatible = "cirrus,cs53l30"; + reg = <0x48>; + reset-gpios = <&gpio 54 0>; + VA-supply = <&cs53l30_va>; + VP-supply = <&cs53l30_vp>; +}; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 4d82a58ff6b0..0aca818dce0f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -57,6 +57,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_CS42XX8_I2C if I2C select SND_SOC_CS4349 if I2C select SND_SOC_CS47L24 if MFD_CS47L24 + select SND_SOC_CS53L30 if I2C select SND_SOC_CX20442 if TTY select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI select SND_SOC_DA7213 if I2C @@ -450,6 +451,11 @@ config SND_SOC_CS4349 config SND_SOC_CS47L24 tristate +# Cirrus Logic Quad-Channel ADC +config SND_SOC_CS53L30 + tristate "Cirrus Logic CS53L30 CODEC" + depends on I2C + config SND_SOC_CX20442 tristate depends on TTY diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 0f548fd34ca3..7151c08c5571 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -49,6 +49,7 @@ snd-soc-cs42xx8-objs := cs42xx8.o snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o snd-soc-cs4349-objs := cs4349.o snd-soc-cs47l24-objs := cs47l24.o +snd-soc-cs53l30-objs := cs53l30.o snd-soc-cx20442-objs := cx20442.o snd-soc-da7210-objs := da7210.o snd-soc-da7213-objs := da7213.o @@ -264,6 +265,7 @@ obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o +obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c new file mode 100644 index 000000000000..714e5799284f --- /dev/null +++ b/sound/soc/codecs/cs53l30.c @@ -0,0 +1,1097 @@ +/* + * cs53l30.c -- CS53l30 ALSA Soc Audio driver + * + * Copyright 2015 Cirrus Logic, Inc. + * + * Authors: Paul Handrigan , + * Tim Howe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cs53l30.h" + +#define CS53L30_NUM_SUPPLIES 2 +static const char *const cs53l30_supply_names[CS53L30_NUM_SUPPLIES] = { + "VA", + "VP", +}; + +struct cs53l30_private { + struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES]; + struct regmap *regmap; + struct gpio_desc *reset_gpio; + struct clk *mclk; + bool use_sdout2; + u32 mclk_rate; +}; + +static const struct reg_default cs53l30_reg_defaults[] = { + { CS53L30_PWRCTL, CS53L30_PWRCTL_DEFAULT }, + { CS53L30_MCLKCTL, CS53L30_MCLKCTL_DEFAULT }, + { CS53L30_INT_SR_CTL, CS53L30_INT_SR_CTL_DEFAULT }, + { CS53L30_MICBIAS_CTL, CS53L30_MICBIAS_CTL_DEFAULT }, + { CS53L30_ASPCFG_CTL, CS53L30_ASPCFG_CTL_DEFAULT }, + { CS53L30_ASP_CTL1, CS53L30_ASP_CTL1_DEFAULT }, + { CS53L30_ASP_TDMTX_CTL1, CS53L30_ASP_TDMTX_CTLx_DEFAULT }, + { CS53L30_ASP_TDMTX_CTL2, CS53L30_ASP_TDMTX_CTLx_DEFAULT }, + { CS53L30_ASP_TDMTX_CTL3, CS53L30_ASP_TDMTX_CTLx_DEFAULT }, + { CS53L30_ASP_TDMTX_CTL4, CS53L30_ASP_TDMTX_CTLx_DEFAULT }, + { CS53L30_ASP_TDMTX_EN1, CS53L30_ASP_TDMTX_ENx_DEFAULT }, + { CS53L30_ASP_TDMTX_EN2, CS53L30_ASP_TDMTX_ENx_DEFAULT }, + { CS53L30_ASP_TDMTX_EN3, CS53L30_ASP_TDMTX_ENx_DEFAULT }, + { CS53L30_ASP_TDMTX_EN4, CS53L30_ASP_TDMTX_ENx_DEFAULT }, + { CS53L30_ASP_TDMTX_EN5, CS53L30_ASP_TDMTX_ENx_DEFAULT }, + { CS53L30_ASP_TDMTX_EN6, CS53L30_ASP_TDMTX_ENx_DEFAULT }, + { CS53L30_ASP_CTL2, CS53L30_ASP_CTL2_DEFAULT }, + { CS53L30_SFT_RAMP, CS53L30_SFT_RMP_DEFAULT }, + { CS53L30_LRCK_CTL1, CS53L30_LRCK_CTLx_DEFAULT }, + { CS53L30_LRCK_CTL2, CS53L30_LRCK_CTLx_DEFAULT }, + { CS53L30_MUTEP_CTL1, CS53L30_MUTEP_CTL1_DEFAULT }, + { CS53L30_MUTEP_CTL2, CS53L30_MUTEP_CTL2_DEFAULT }, + { CS53L30_INBIAS_CTL1, CS53L30_INBIAS_CTL1_DEFAULT }, + { CS53L30_INBIAS_CTL2, CS53L30_INBIAS_CTL2_DEFAULT }, + { CS53L30_DMIC1_STR_CTL, CS53L30_DMIC1_STR_CTL_DEFAULT }, + { CS53L30_DMIC2_STR_CTL, CS53L30_DMIC2_STR_CTL_DEFAULT }, + { CS53L30_ADCDMIC1_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT }, + { CS53L30_ADCDMIC1_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT }, + { CS53L30_ADC1_CTL3, CS53L30_ADCx_CTL3_DEFAULT }, + { CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT }, + { CS53L30_ADC1A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT }, + { CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT }, + { CS53L30_ADC1A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT }, + { CS53L30_ADC1B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT }, + { CS53L30_ADCDMIC2_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT }, + { CS53L30_ADCDMIC2_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT }, + { CS53L30_ADC2_CTL3, CS53L30_ADCx_CTL3_DEFAULT }, + { CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT }, + { CS53L30_ADC2A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT }, + { CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT }, + { CS53L30_ADC2A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT }, + { CS53L30_ADC2B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT }, + { CS53L30_INT_MASK, CS53L30_DEVICE_INT_MASK }, +}; + +static bool cs53l30_volatile_register(struct device *dev, unsigned int reg) +{ + if (reg == CS53L30_IS) + return true; + else + return false; +} + +static bool cs53l30_writeable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS53L30_DEVID_AB: + case CS53L30_DEVID_CD: + case CS53L30_DEVID_E: + case CS53L30_REVID: + case CS53L30_IS: + return false; + default: + return true; + } +} + +static bool cs53l30_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS53L30_DEVID_AB: + case CS53L30_DEVID_CD: + case CS53L30_DEVID_E: + case CS53L30_REVID: + case CS53L30_PWRCTL: + case CS53L30_MCLKCTL: + case CS53L30_INT_SR_CTL: + case CS53L30_MICBIAS_CTL: + case CS53L30_ASPCFG_CTL: + case CS53L30_ASP_CTL1: + case CS53L30_ASP_TDMTX_CTL1: + case CS53L30_ASP_TDMTX_CTL2: + case CS53L30_ASP_TDMTX_CTL3: + case CS53L30_ASP_TDMTX_CTL4: + case CS53L30_ASP_TDMTX_EN1: + case CS53L30_ASP_TDMTX_EN2: + case CS53L30_ASP_TDMTX_EN3: + case CS53L30_ASP_TDMTX_EN4: + case CS53L30_ASP_TDMTX_EN5: + case CS53L30_ASP_TDMTX_EN6: + case CS53L30_ASP_CTL2: + case CS53L30_SFT_RAMP: + case CS53L30_LRCK_CTL1: + case CS53L30_LRCK_CTL2: + case CS53L30_MUTEP_CTL1: + case CS53L30_MUTEP_CTL2: + case CS53L30_INBIAS_CTL1: + case CS53L30_INBIAS_CTL2: + case CS53L30_DMIC1_STR_CTL: + case CS53L30_DMIC2_STR_CTL: + case CS53L30_ADCDMIC1_CTL1: + case CS53L30_ADCDMIC1_CTL2: + case CS53L30_ADC1_CTL3: + case CS53L30_ADC1_NG_CTL: + case CS53L30_ADC1A_AFE_CTL: + case CS53L30_ADC1B_AFE_CTL: + case CS53L30_ADC1A_DIG_VOL: + case CS53L30_ADC1B_DIG_VOL: + case CS53L30_ADCDMIC2_CTL1: + case CS53L30_ADCDMIC2_CTL2: + case CS53L30_ADC2_CTL3: + case CS53L30_ADC2_NG_CTL: + case CS53L30_ADC2A_AFE_CTL: + case CS53L30_ADC2B_AFE_CTL: + case CS53L30_ADC2A_DIG_VOL: + case CS53L30_ADC2B_DIG_VOL: + case CS53L30_INT_MASK: + return true; + default: + return false; + } +} + +static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2000, 0); +static DECLARE_TLV_DB_SCALE(adc_ng_boost_tlv, 0, 3000, 0); +static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); +static DECLARE_TLV_DB_SCALE(dig_tlv, -9600, 100, 1); +static DECLARE_TLV_DB_SCALE(pga_preamp_tlv, 0, 10000, 0); + +static const char * const input1_sel_text[] = { + "DMIC1 On AB In", + "DMIC1 On A In", + "DMIC1 On B In", + "ADC1 On AB In", + "ADC1 On A In", + "ADC1 On B In", + "DMIC1 Off ADC1 Off", +}; + +unsigned int const input1_sel_values[] = { + CS53L30_CH_TYPE, + CS53L30_ADCxB_PDN | CS53L30_CH_TYPE, + CS53L30_ADCxA_PDN | CS53L30_CH_TYPE, + CS53L30_DMICx_PDN, + CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN, + CS53L30_ADCxA_PDN | CS53L30_DMICx_PDN, + CS53L30_ADCxA_PDN | CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN, +}; + +static const char * const input2_sel_text[] = { + "DMIC2 On AB In", + "DMIC2 On A In", + "DMIC2 On B In", + "ADC2 On AB In", + "ADC2 On A In", + "ADC2 On B In", + "DMIC2 Off ADC2 Off", +}; + +unsigned int const input2_sel_values[] = { + 0x0, + CS53L30_ADCxB_PDN, + CS53L30_ADCxA_PDN, + CS53L30_DMICx_PDN, + CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN, + CS53L30_ADCxA_PDN | CS53L30_DMICx_PDN, + CS53L30_ADCxA_PDN | CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN, +}; + +static const char * const input1_route_sel_text[] = { + "ADC1_SEL", "DMIC1_SEL", +}; + +static const struct soc_enum input1_route_sel_enum = + SOC_ENUM_SINGLE(CS53L30_ADCDMIC1_CTL1, CS53L30_CH_TYPE_SHIFT, + ARRAY_SIZE(input1_route_sel_text), + input1_route_sel_text); + +static SOC_VALUE_ENUM_SINGLE_DECL(input1_sel_enum, CS53L30_ADCDMIC1_CTL1, 0, + CS53L30_ADCDMICx_PDN_MASK, input1_sel_text, + input1_sel_values); + +static const struct snd_kcontrol_new input1_route_sel_mux = + SOC_DAPM_ENUM("Input 1 Route", input1_route_sel_enum); + +static const char * const input2_route_sel_text[] = { + "ADC2_SEL", "DMIC2_SEL", +}; + +/* Note: CS53L30_ADCDMIC1_CTL1 CH_TYPE controls inputs 1 and 2 */ +static const struct soc_enum input2_route_sel_enum = + SOC_ENUM_SINGLE(CS53L30_ADCDMIC1_CTL1, 0, + ARRAY_SIZE(input2_route_sel_text), + input2_route_sel_text); + +static SOC_VALUE_ENUM_SINGLE_DECL(input2_sel_enum, CS53L30_ADCDMIC2_CTL1, 0, + CS53L30_ADCDMICx_PDN_MASK, input2_sel_text, + input2_sel_values); + +static const struct snd_kcontrol_new input2_route_sel_mux = + SOC_DAPM_ENUM("Input 2 Route", input2_route_sel_enum); + +/* + * TB = 6144*(MCLK(int) scaling factor)/MCLK(internal) + * TB - Time base + * NOTE: If MCLK_INT_SCALE = 0, then TB=1 + */ +static const char * const cs53l30_ng_delay_text[] = { + "TB*50ms", "TB*100ms", "TB*150ms", "TB*200ms", +}; + +static const struct soc_enum adc1_ng_delay_enum = + SOC_ENUM_SINGLE(CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_DELAY_SHIFT, + ARRAY_SIZE(cs53l30_ng_delay_text), + cs53l30_ng_delay_text); + +static const struct soc_enum adc2_ng_delay_enum = + SOC_ENUM_SINGLE(CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_DELAY_SHIFT, + ARRAY_SIZE(cs53l30_ng_delay_text), + cs53l30_ng_delay_text); + +/* The noise gate threshold selected will depend on NG Boost */ +static const char * const cs53l30_ng_thres_text[] = { + "-64dB/-34dB", "-66dB/-36dB", "-70dB/-40dB", "-73dB/-43dB", + "-76dB/-46dB", "-82dB/-52dB", "-58dB", "-64dB", +}; + +static const struct soc_enum adc1_ng_thres_enum = + SOC_ENUM_SINGLE(CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_THRESH_SHIFT, + ARRAY_SIZE(cs53l30_ng_thres_text), + cs53l30_ng_thres_text); + +static const struct soc_enum adc2_ng_thres_enum = + SOC_ENUM_SINGLE(CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_THRESH_SHIFT, + ARRAY_SIZE(cs53l30_ng_thres_text), + cs53l30_ng_thres_text); + +/* Corner frequencies are with an Fs of 48kHz. */ +static const char * const hpf_corner_freq_text[] = { + "1.86Hz", "120Hz", "235Hz", "466Hz", +}; + +static const struct soc_enum adc1_hpf_enum = + SOC_ENUM_SINGLE(CS53L30_ADC1_CTL3, CS53L30_ADCx_HPF_CF_SHIFT, + ARRAY_SIZE(hpf_corner_freq_text), hpf_corner_freq_text); + +static const struct soc_enum adc2_hpf_enum = + SOC_ENUM_SINGLE(CS53L30_ADC2_CTL3, CS53L30_ADCx_HPF_CF_SHIFT, + ARRAY_SIZE(hpf_corner_freq_text), hpf_corner_freq_text); + +static const struct snd_kcontrol_new cs53l30_snd_controls[] = { + SOC_SINGLE("Digital Soft-Ramp Switch", CS53L30_SFT_RAMP, + CS53L30_DIGSFT_SHIFT, 1, 0), + SOC_SINGLE("ADC1 Noise Gate Ganging Switch", CS53L30_ADC1_CTL3, + CS53L30_ADCx_NG_ALL_SHIFT, 1, 0), + SOC_SINGLE("ADC2 Noise Gate Ganging Switch", CS53L30_ADC2_CTL3, + CS53L30_ADCx_NG_ALL_SHIFT, 1, 0), + SOC_SINGLE("ADC1A Noise Gate Enable Switch", CS53L30_ADC1_NG_CTL, + CS53L30_ADCxA_NG_SHIFT, 1, 0), + SOC_SINGLE("ADC1B Noise Gate Enable Switch", CS53L30_ADC1_NG_CTL, + CS53L30_ADCxB_NG_SHIFT, 1, 0), + SOC_SINGLE("ADC2A Noise Gate Enable Switch", CS53L30_ADC2_NG_CTL, + CS53L30_ADCxA_NG_SHIFT, 1, 0), + SOC_SINGLE("ADC2B Noise Gate Enable Switch", CS53L30_ADC2_NG_CTL, + CS53L30_ADCxB_NG_SHIFT, 1, 0), + SOC_SINGLE("ADC1 Notch Filter Switch", CS53L30_ADCDMIC1_CTL2, + CS53L30_ADCx_NOTCH_DIS_SHIFT, 1, 1), + SOC_SINGLE("ADC2 Notch Filter Switch", CS53L30_ADCDMIC2_CTL2, + CS53L30_ADCx_NOTCH_DIS_SHIFT, 1, 1), + SOC_SINGLE("ADC1A Invert Switch", CS53L30_ADCDMIC1_CTL2, + CS53L30_ADCxA_INV_SHIFT, 1, 0), + SOC_SINGLE("ADC1B Invert Switch", CS53L30_ADCDMIC1_CTL2, + CS53L30_ADCxB_INV_SHIFT, 1, 0), + SOC_SINGLE("ADC2A Invert Switch", CS53L30_ADCDMIC2_CTL2, + CS53L30_ADCxA_INV_SHIFT, 1, 0), + SOC_SINGLE("ADC2B Invert Switch", CS53L30_ADCDMIC2_CTL2, + CS53L30_ADCxB_INV_SHIFT, 1, 0), + + SOC_SINGLE_TLV("ADC1A Digital Boost Volume", CS53L30_ADCDMIC1_CTL2, + CS53L30_ADCxA_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv), + SOC_SINGLE_TLV("ADC1B Digital Boost Volume", CS53L30_ADCDMIC1_CTL2, + CS53L30_ADCxB_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv), + SOC_SINGLE_TLV("ADC2A Digital Boost Volume", CS53L30_ADCDMIC2_CTL2, + CS53L30_ADCxA_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv), + SOC_SINGLE_TLV("ADC2B Digital Boost Volume", CS53L30_ADCDMIC2_CTL2, + CS53L30_ADCxB_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv), + SOC_SINGLE_TLV("ADC1 NG Boost Volume", CS53L30_ADC1_NG_CTL, + CS53L30_ADCx_NG_BOOST_SHIFT, 1, 0, adc_ng_boost_tlv), + SOC_SINGLE_TLV("ADC2 NG Boost Volume", CS53L30_ADC2_NG_CTL, + CS53L30_ADCx_NG_BOOST_SHIFT, 1, 0, adc_ng_boost_tlv), + + SOC_DOUBLE_R_TLV("ADC1 Pre Amp Gain", CS53L30_ADC1A_AFE_CTL, + CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_PREAMP_SHIFT, + 2, 0, pga_preamp_tlv), + SOC_DOUBLE_R_TLV("ADC2 Pre Amp Gain", CS53L30_ADC2A_AFE_CTL, + CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_PREAMP_SHIFT, + 2, 0, pga_preamp_tlv), + + SOC_ENUM("Input 1 Channel Select", input1_sel_enum), + SOC_ENUM("Input 2 Channel Select", input2_sel_enum), + + SOC_ENUM("ADC1 HPF Select", adc1_hpf_enum), + SOC_ENUM("ADC2 HPF Select", adc2_hpf_enum), + SOC_ENUM("ADC1 NG Threshold", adc1_ng_thres_enum), + SOC_ENUM("ADC2 NG Threshold", adc2_ng_thres_enum), + SOC_ENUM("ADC1 NG Delay", adc1_ng_delay_enum), + SOC_ENUM("ADC2 NG Delay", adc2_ng_delay_enum), + + SOC_SINGLE_SX_TLV("ADC1A PGA Volume", + CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + SOC_SINGLE_SX_TLV("ADC1B PGA Volume", + CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + SOC_SINGLE_SX_TLV("ADC2A PGA Volume", + CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + SOC_SINGLE_SX_TLV("ADC2B PGA Volume", + CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + + SOC_SINGLE_SX_TLV("ADC1A Digital Volume", + CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + SOC_SINGLE_SX_TLV("ADC1B Digital Volume", + CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + SOC_SINGLE_SX_TLV("ADC2A Digital Volume", + CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + SOC_SINGLE_SX_TLV("ADC2B Digital Volume", + CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), +}; + +static const struct snd_soc_dapm_widget cs53l30_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN1_DMIC1"), + SND_SOC_DAPM_INPUT("IN2"), + SND_SOC_DAPM_INPUT("IN3_DMIC2"), + SND_SOC_DAPM_INPUT("IN4"), + SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS53L30_MICBIAS_CTL, + CS53L30_MIC1_BIAS_PDN_SHIFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS53L30_MICBIAS_CTL, + CS53L30_MIC2_BIAS_PDN_SHIFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("MIC3 Bias", CS53L30_MICBIAS_CTL, + CS53L30_MIC3_BIAS_PDN_SHIFT, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("MIC4 Bias", CS53L30_MICBIAS_CTL, + CS53L30_MIC4_BIAS_PDN_SHIFT, 1, NULL, 0), + + SND_SOC_DAPM_AIF_OUT("ASP_SDOUT1", NULL, 0, CS53L30_ASP_CTL1, + CS53L30_ASP_SDOUTx_PDN_SHIFT, 1), + SND_SOC_DAPM_AIF_OUT("ASP_SDOUT2", NULL, 0, CS53L30_ASP_CTL2, + CS53L30_ASP_SDOUTx_PDN_SHIFT, 1), + + SND_SOC_DAPM_MUX("Input Mux 1", SND_SOC_NOPM, 0, 0, + &input1_route_sel_mux), + SND_SOC_DAPM_MUX("Input Mux 2", SND_SOC_NOPM, 0, 0, + &input2_route_sel_mux), + + SND_SOC_DAPM_ADC("ADC1A", NULL, CS53L30_ADCDMIC1_CTL1, + CS53L30_ADCxA_PDN_SHIFT, 1), + SND_SOC_DAPM_ADC("ADC1B", NULL, CS53L30_ADCDMIC1_CTL1, + CS53L30_ADCxB_PDN_SHIFT, 1), + SND_SOC_DAPM_ADC("ADC2A", NULL, CS53L30_ADCDMIC2_CTL1, + CS53L30_ADCxA_PDN_SHIFT, 1), + SND_SOC_DAPM_ADC("ADC2B", NULL, CS53L30_ADCDMIC2_CTL1, + CS53L30_ADCxB_PDN_SHIFT, 1), + SND_SOC_DAPM_ADC("DMIC1", NULL, CS53L30_ADCDMIC1_CTL1, + CS53L30_DMICx_PDN_SHIFT, 1), + SND_SOC_DAPM_ADC("DMIC2", NULL, CS53L30_ADCDMIC2_CTL1, + CS53L30_DMICx_PDN_SHIFT, 1), +}; + +static const struct snd_soc_dapm_route cs53l30_dapm_routes[] = { + /* ADC Input Paths */ + {"ADC1A", NULL, "IN1_DMIC1"}, + {"Input Mux 1", "ADC1_SEL", "ADC1A"}, + {"ADC1B", NULL, "IN2"}, + + {"ADC2A", NULL, "IN3_DMIC2"}, + {"Input Mux 2", "ADC2_SEL", "ADC2A"}, + {"ADC2B", NULL, "IN4"}, + + /* MIC Bias Paths */ + {"ADC1A", NULL, "MIC1 Bias"}, + {"ADC1B", NULL, "MIC2 Bias"}, + {"ADC2A", NULL, "MIC3 Bias"}, + {"ADC2B", NULL, "MIC4 Bias"}, + + /* DMIC Paths */ + {"DMIC1", NULL, "IN1_DMIC1"}, + {"Input Mux 1", "DMIC1_SEL", "DMIC1"}, + + {"DMIC2", NULL, "IN3_DMIC2"}, + {"Input Mux 2", "DMIC2_SEL", "DMIC2"}, +}; + +static const struct snd_soc_dapm_route cs53l30_dapm_routes_sdout1[] = { + /* Output Paths when using SDOUT1 only */ + {"ASP_SDOUT1", NULL, "ADC1A" }, + {"ASP_SDOUT1", NULL, "Input Mux 1"}, + {"ASP_SDOUT1", NULL, "ADC1B"}, + + {"ASP_SDOUT1", NULL, "ADC2A"}, + {"ASP_SDOUT1", NULL, "Input Mux 2"}, + {"ASP_SDOUT1", NULL, "ADC2B"}, + + {"Capture", NULL, "ASP_SDOUT1"}, +}; + +static const struct snd_soc_dapm_route cs53l30_dapm_routes_sdout2[] = { + /* Output Paths when using both SDOUT1 and SDOUT2 */ + {"ASP_SDOUT1", NULL, "ADC1A" }, + {"ASP_SDOUT1", NULL, "Input Mux 1"}, + {"ASP_SDOUT1", NULL, "ADC1B"}, + + {"ASP_SDOUT2", NULL, "ADC2A"}, + {"ASP_SDOUT2", NULL, "Input Mux 2"}, + {"ASP_SDOUT2", NULL, "ADC2B"}, + + {"Capture", NULL, "ASP_SDOUT1"}, + {"Capture", NULL, "ASP_SDOUT2"}, +}; + +struct cs53l30_mclk_div { + u32 mclk_rate; + u32 srate; + u8 asp_rate; + u8 internal_fs_ratio; + u8 mclk_int_scale; +}; + +static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = { + /* NOTE: Enable MCLK_INT_SCALE to save power. */ + + /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */ + {5644800, 11025, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {5644800, 22050, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {5644800, 44100, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + + {6000000, 8000, 0x1, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 11025, 0x2, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 12000, 0x4, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 16000, 0x5, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 22050, 0x6, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 24000, 0x8, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 32000, 0x9, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 44100, 0xA, 0, CS53L30_MCLK_INT_SCALE}, + {6000000, 48000, 0xC, 0, CS53L30_MCLK_INT_SCALE}, + + {6144000, 8000, 0x1, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 11025, 0x2, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 12000, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 16000, 0x5, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 22050, 0x6, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 24000, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 32000, 0x9, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 44100, 0xA, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6144000, 48000, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + + {6400000, 8000, 0x1, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 11025, 0x2, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 12000, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 16000, 0x5, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 22050, 0x6, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 24000, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 32000, 0x9, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 44100, 0xA, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, + {6400000, 48000, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE}, +}; + +struct cs53l30_mclkx_div { + u32 mclkx; + u8 ratio; + u8 mclkdiv; +}; + +static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = { + {5644800, 1, CS53L30_MCLK_DIV_BY_1}, + {6000000, 1, CS53L30_MCLK_DIV_BY_1}, + {6144000, 1, CS53L30_MCLK_DIV_BY_1}, + {11289600, 2, CS53L30_MCLK_DIV_BY_2}, + {12288000, 2, CS53L30_MCLK_DIV_BY_2}, + {12000000, 2, CS53L30_MCLK_DIV_BY_2}, + {19200000, 3, CS53L30_MCLK_DIV_BY_3}, +}; + +static int cs53l30_get_mclkx_coeff(int mclkx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs53l30_mclkx_coeffs); i++) { + if (cs53l30_mclkx_coeffs[i].mclkx == mclkx) + return i; + } + + return -EINVAL; +} + +static int cs53l30_get_mclk_coeff(int mclk_rate, int srate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs53l30_mclk_coeffs); i++) { + if (cs53l30_mclk_coeffs[i].mclk_rate == mclk_rate && + cs53l30_mclk_coeffs[i].srate == srate) + return i; + } + + return -EINVAL; +} + +static int cs53l30_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); + int mclkx_coeff; + u32 mclk_rate; + + /* MCLKX -> MCLK */ + mclkx_coeff = cs53l30_get_mclkx_coeff(freq); + if (mclkx_coeff < 0) + return mclkx_coeff; + + mclk_rate = cs53l30_mclkx_coeffs[mclkx_coeff].mclkx / + cs53l30_mclkx_coeffs[mclkx_coeff].ratio; + + regmap_update_bits(priv->regmap, CS53L30_MCLKCTL, + CS53L30_MCLK_DIV_MASK, + cs53l30_mclkx_coeffs[mclkx_coeff].mclkdiv); + + priv->mclk_rate = mclk_rate; + + return 0; +} + +static int cs53l30_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); + u8 aspcfg = 0, aspctl1 = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + aspcfg |= CS53L30_ASP_MS; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + /* DAI mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + /* Set TDM_PDN to turn off TDM mode -- Reset default */ + aspctl1 |= CS53L30_ASP_TDM_PDN; + break; + case SND_SOC_DAIFMT_DSP_A: + /* Clear TDM_PDN and SHIFT_LEFT, invert SCLK */ + aspcfg |= CS53L30_ASP_SCLK_INV; + break; + default: + return -EINVAL; + } + + /* Check to see if the SCLK is inverted */ + if (fmt & (SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_IB_IF)) + aspcfg ^= CS53L30_ASP_SCLK_INV; + + regmap_update_bits(priv->regmap, CS53L30_ASPCFG_CTL, + CS53L30_ASP_MS | CS53L30_ASP_SCLK_INV, aspcfg); + + regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1, + CS53L30_ASP_TDM_PDN | CS53L30_SHIFT_LEFT, aspctl1); + + return 0; +} + +static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); + int srate = params_rate(params); + int mclk_coeff; + + /* MCLK -> srate */ + mclk_coeff = cs53l30_get_mclk_coeff(priv->mclk_rate, srate); + if (mclk_coeff < 0) + return -EINVAL; + + regmap_update_bits(priv->regmap, CS53L30_INT_SR_CTL, + CS53L30_INTRNL_FS_RATIO_MASK, + cs53l30_mclk_coeffs[mclk_coeff].internal_fs_ratio); + + regmap_update_bits(priv->regmap, CS53L30_MCLKCTL, + CS53L30_MCLK_INT_SCALE_MASK, + cs53l30_mclk_coeffs[mclk_coeff].mclk_int_scale); + + regmap_update_bits(priv->regmap, CS53L30_ASPCFG_CTL, + CS53L30_ASP_RATE_MASK, + cs53l30_mclk_coeffs[mclk_coeff].asp_rate); + + return 0; +} + +static int cs53l30_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec); + unsigned int reg; + int i, inter_max_check, ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + case SND_SOC_BIAS_PREPARE: + if (dapm->bias_level == SND_SOC_BIAS_STANDBY) + regmap_update_bits(priv->regmap, CS53L30_PWRCTL, + CS53L30_PDN_LP_MASK, 0); + break; + case SND_SOC_BIAS_STANDBY: + if (dapm->bias_level == SND_SOC_BIAS_OFF) { + ret = clk_prepare_enable(priv->mclk); + if (ret) { + dev_err(codec->dev, + "failed to enable MCLK: %d\n", ret); + return ret; + } + regmap_update_bits(priv->regmap, CS53L30_MCLKCTL, + CS53L30_MCLK_DIS_MASK, 0); + regmap_update_bits(priv->regmap, CS53L30_PWRCTL, + CS53L30_PDN_ULP_MASK, 0); + msleep(50); + } else { + regmap_update_bits(priv->regmap, CS53L30_PWRCTL, + CS53L30_PDN_ULP_MASK, + CS53L30_PDN_ULP); + } + break; + case SND_SOC_BIAS_OFF: + regmap_update_bits(priv->regmap, CS53L30_INT_MASK, + CS53L30_PDN_DONE, 0); + /* + * If digital softramp is set, the amount of time required + * for power down increases and depends on the digital + * volume setting. + */ + + /* Set the max possible time if digsft is set */ + regmap_read(priv->regmap, CS53L30_SFT_RAMP, ®); + if (reg & CS53L30_DIGSFT_MASK) + inter_max_check = CS53L30_PDN_POLL_MAX; + else + inter_max_check = 10; + + regmap_update_bits(priv->regmap, CS53L30_PWRCTL, + CS53L30_PDN_ULP_MASK, + CS53L30_PDN_ULP); + /* PDN_DONE will take a min of 20ms to be set.*/ + msleep(20); + /* Clr status */ + regmap_read(priv->regmap, CS53L30_IS, ®); + for (i = 0; i < inter_max_check; i++) { + if (inter_max_check < 10) { + usleep_range(1000, 1100); + regmap_read(priv->regmap, CS53L30_IS, ®); + if (reg & CS53L30_PDN_DONE) + break; + } else { + usleep_range(10000, 10100); + regmap_read(priv->regmap, CS53L30_IS, ®); + if (reg & CS53L30_PDN_DONE) + break; + } + } + /* PDN_DONE is set. We now can disable the MCLK */ + regmap_update_bits(priv->regmap, CS53L30_INT_MASK, + CS53L30_PDN_DONE, CS53L30_PDN_DONE); + regmap_update_bits(priv->regmap, CS53L30_MCLKCTL, + CS53L30_MCLK_DIS_MASK, + CS53L30_MCLK_DIS); + clk_disable_unprepare(priv->mclk); + break; + } + + return 0; +} + +static int cs53l30_set_tristate(struct snd_soc_dai *dai, int tristate) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); + u8 val = tristate ? CS53L30_ASP_3ST : 0; + + return regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1, + CS53L30_ASP_3ST_MASK, val); +} + +unsigned int const cs53l30_src_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 +}; + +static struct snd_pcm_hw_constraint_list src_constraints = { + .count = ARRAY_SIZE(cs53l30_src_rates), + .list = cs53l30_src_rates, +}; + +static int cs53l30_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &src_constraints); + + return 0; +} + +/* + * Note: CS53L30 counts the slot number per byte while ASoC counts the slot + * number per slot_width. So there is a difference between the slots of ASoC + * and the slots of CS53L30. + */ +static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); + unsigned int loc[CS53L30_TDM_SLOT_MAX] = {48, 48, 48, 48}; + unsigned int slot_next, slot_step; + u64 tx_enable = 0; + int i; + + if (!rx_mask) { + dev_err(dai->dev, "rx masks must not be 0\n"); + return -EINVAL; + } + + /* Assuming slot_width is not supposed to be greater than 64 */ + if (slots <= 0 || slot_width <= 0 || slot_width > 64) { + dev_err(dai->dev, "invalid slot number or slot width\n"); + return -EINVAL; + } + + if (slot_width & 0x7) { + dev_err(dai->dev, "slot width must count in byte\n"); + return -EINVAL; + } + + /* How many bytes in each ASoC slot */ + slot_step = slot_width >> 3; + + for (i = 0; rx_mask && i < CS53L30_TDM_SLOT_MAX; i++) { + /* Find the first slot from LSB */ + slot_next = __ffs(rx_mask); + /* Save the slot location by converting to CS53L30 slot */ + loc[i] = slot_next * slot_step; + /* Create the mask of CS53L30 slot */ + tx_enable |= (u64)((u64)(1 << slot_step) - 1) << (u64)loc[i]; + /* Clear this slot from rx_mask */ + rx_mask &= ~(1 << slot_next); + } + + /* Error out to avoid slot shift */ + if (rx_mask && i == CS53L30_TDM_SLOT_MAX) { + dev_err(dai->dev, "rx_mask exceeds max slot number: %d\n", + CS53L30_TDM_SLOT_MAX); + return -EINVAL; + } + + /* Validate the last CS53L30 slot */ + slot_next = loc[CS53L30_TDM_SLOT_MAX - 1] + slot_step - 1; + if (slot_next > 47) { + dev_err(dai->dev, "slot selection out of bounds: %u\n", + slot_next); + return -EINVAL; + } + + for (i = 0; i < CS53L30_TDM_SLOT_MAX && loc[i] != 48; i++) { + regmap_update_bits(priv->regmap, CS53L30_ASP_TDMTX_CTL(i), + CS53L30_ASP_CHx_TX_LOC_MASK, loc[i]); + dev_dbg(dai->dev, "loc[%d]=%x\n", i, loc[i]); + } + + for (i = 0; i < CS53L30_ASP_TDMTX_ENx_MAX && tx_enable; i++) { + regmap_write(priv->regmap, CS53L30_ASP_TDMTX_ENx(i), + tx_enable & 0xff); + tx_enable >>= 8; + dev_dbg(dai->dev, "en_reg=%x, tx_enable=%llx\n", + CS53L30_ASP_TDMTX_ENx(i), tx_enable & 0xff); + } + + return 0; +} + +/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ +#define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) + +#define CS53L30_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +static const struct snd_soc_dai_ops cs53l30_ops = { + .startup = cs53l30_pcm_startup, + .hw_params = cs53l30_pcm_hw_params, + .set_fmt = cs53l30_set_dai_fmt, + .set_sysclk = cs53l30_set_sysclk, + .set_tristate = cs53l30_set_tristate, + .set_tdm_slot = cs53l30_set_dai_tdm_slot, +}; + +static struct snd_soc_dai_driver cs53l30_dai = { + .name = "cs53l30", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = CS53L30_RATES, + .formats = CS53L30_FORMATS, + }, + .ops = &cs53l30_ops, + .symmetric_rates = 1, +}; + +static int cs53l30_codec_probe(struct snd_soc_codec *codec) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + if (priv->use_sdout2) + snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout2, + ARRAY_SIZE(cs53l30_dapm_routes_sdout2)); + else + snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout1, + ARRAY_SIZE(cs53l30_dapm_routes_sdout1)); + + return 0; +} + +static struct snd_soc_codec_driver cs53l30_driver = { + .probe = cs53l30_codec_probe, + .set_bias_level = cs53l30_set_bias_level, + + .dapm_widgets = cs53l30_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets), + .dapm_routes = cs53l30_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), + + .controls = cs53l30_snd_controls, + .num_controls = ARRAY_SIZE(cs53l30_snd_controls), +}; + +static struct regmap_config cs53l30_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = CS53L30_MAX_REGISTER, + .reg_defaults = cs53l30_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs53l30_reg_defaults), + .volatile_reg = cs53l30_volatile_register, + .writeable_reg = cs53l30_writeable_register, + .readable_reg = cs53l30_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + +static int cs53l30_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const struct device_node *np = client->dev.of_node; + struct device *dev = &client->dev; + struct cs53l30_private *cs53l30; + unsigned int devid = 0; + unsigned int reg; + int ret = 0, i; + u8 val; + + cs53l30 = devm_kzalloc(dev, sizeof(*cs53l30), GFP_KERNEL); + if (!cs53l30) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(cs53l30->supplies); i++) + cs53l30->supplies[i].supply = cs53l30_supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs53l30->supplies), + cs53l30->supplies); + if (ret) { + dev_err(dev, "failed to get supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(cs53l30->supplies), + cs53l30->supplies); + if (ret) { + dev_err(dev, "failed to enable supplies: %d\n", ret); + return ret; + } + + /* Reset the Device */ + cs53l30->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(cs53l30->reset_gpio)) { + ret = PTR_ERR(cs53l30->reset_gpio); + goto error; + } + + if (cs53l30->reset_gpio) + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + + i2c_set_clientdata(client, cs53l30); + + cs53l30->mclk_rate = 0; + + cs53l30->regmap = devm_regmap_init_i2c(client, &cs53l30_regmap); + if (IS_ERR(cs53l30->regmap)) { + ret = PTR_ERR(cs53l30->regmap); + dev_err(dev, "regmap_init() failed: %d\n", ret); + goto error; + } + + /* Initialize codec */ + ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_AB, ®); + devid = reg << 12; + + ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_CD, ®); + devid |= reg << 4; + + ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_E, ®); + devid |= (reg & 0xF0) >> 4; + + if (devid != CS53L30_DEVID) { + ret = -ENODEV; + dev_err(dev, "Device ID (%X). Expected %X\n", + devid, CS53L30_DEVID); + goto error; + } + + ret = regmap_read(cs53l30->regmap, CS53L30_REVID, ®); + if (ret < 0) { + dev_err(dev, "failed to get Revision ID: %d\n", ret); + goto error; + } + + /* Check if MCLK provided */ + cs53l30->mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(cs53l30->mclk)) { + if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto error; + } + /* Otherwise mark the mclk pointer to NULL */ + cs53l30->mclk = NULL; + } + + if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val)) + regmap_update_bits(cs53l30->regmap, CS53L30_MICBIAS_CTL, + CS53L30_MIC_BIAS_CTRL_MASK, val); + + if (of_property_read_bool(np, "cirrus,use-sdout2")) + cs53l30->use_sdout2 = true; + + dev_info(dev, "Cirrus Logic CS53L30, Revision: %02X\n", reg & 0xFF); + + ret = snd_soc_register_codec(dev, &cs53l30_driver, &cs53l30_dai, 1); + if (ret) { + dev_err(dev, "failed to register codec: %d\n", ret); + goto error; + } + + return 0; + +error: + regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), + cs53l30->supplies); + return ret; +} + +static int cs53l30_i2c_remove(struct i2c_client *client) +{ + struct cs53l30_private *cs53l30 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + + /* Hold down reset */ + if (cs53l30->reset_gpio) + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + + regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), + cs53l30->supplies); + + return 0; +} + +#ifdef CONFIG_PM +static int cs53l30_runtime_suspend(struct device *dev) +{ + struct cs53l30_private *cs53l30 = dev_get_drvdata(dev); + + regcache_cache_only(cs53l30->regmap, true); + + /* Hold down reset */ + if (cs53l30->reset_gpio) + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + + regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), + cs53l30->supplies); + + return 0; +} + +static int cs53l30_runtime_resume(struct device *dev) +{ + struct cs53l30_private *cs53l30 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(cs53l30->supplies), + cs53l30->supplies); + if (ret) { + dev_err(dev, "failed to enable supplies: %d\n", ret); + return ret; + } + + if (cs53l30->reset_gpio) + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + + regcache_cache_only(cs53l30->regmap, false); + regcache_sync(cs53l30->regmap); + + return 0; +} +#endif + +static const struct dev_pm_ops cs53l30_runtime_pm = { + SET_RUNTIME_PM_OPS(cs53l30_runtime_suspend, cs53l30_runtime_resume, + NULL) +}; + +static const struct of_device_id cs53l30_of_match[] = { + { .compatible = "cirrus,cs53l30", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, cs53l30_of_match); + +static const struct i2c_device_id cs53l30_id[] = { + { "cs53l30", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs53l30_id); + +static struct i2c_driver cs53l30_i2c_driver = { + .driver = { + .name = "cs53l30", + .pm = &cs53l30_runtime_pm, + }, + .id_table = cs53l30_id, + .probe = cs53l30_i2c_probe, + .remove = cs53l30_i2c_remove, +}; + +module_i2c_driver(cs53l30_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS53L30 driver"); +MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs53l30.h b/sound/soc/codecs/cs53l30.h new file mode 100644 index 000000000000..0dd4afbb5c64 --- /dev/null +++ b/sound/soc/codecs/cs53l30.h @@ -0,0 +1,458 @@ +/* + * ALSA SoC CS53L30 codec driver + * + * Copyright 2015 Cirrus Logic, Inc. + * + * Author: Paul Handrigan , + * Tim Howe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __CS53L30_H__ +#define __CS53L30_H__ + +/* I2C Registers */ +#define CS53L30_DEVID_AB 0x01 /* Device ID A & B [RO]. */ +#define CS53L30_DEVID_CD 0x02 /* Device ID C & D [RO]. */ +#define CS53L30_DEVID_E 0x03 /* Device ID E [RO]. */ +#define CS53L30_REVID 0x05 /* Revision ID [RO]. */ +#define CS53L30_PWRCTL 0x06 /* Power Control. */ +#define CS53L30_MCLKCTL 0x07 /* MCLK Control. */ +#define CS53L30_INT_SR_CTL 0x08 /* Internal Sample Rate Control. */ +#define CS53L30_MICBIAS_CTL 0x0A /* Mic Bias Control. */ +#define CS53L30_ASPCFG_CTL 0x0C /* ASP Config Control. */ +#define CS53L30_ASP_CTL1 0x0D /* ASP1 Control. */ +#define CS53L30_ASP_TDMTX_CTL1 0x0E /* ASP1 TDM TX Control 1 */ +#define CS53L30_ASP_TDMTX_CTL2 0x0F /* ASP1 TDM TX Control 2 */ +#define CS53L30_ASP_TDMTX_CTL3 0x10 /* ASP1 TDM TX Control 3 */ +#define CS53L30_ASP_TDMTX_CTL4 0x11 /* ASP1 TDM TX Control 4 */ +#define CS53L30_ASP_TDMTX_EN1 0x12 /* ASP1 TDM TX Enable 1 */ +#define CS53L30_ASP_TDMTX_EN2 0x13 /* ASP1 TDM TX Enable 2 */ +#define CS53L30_ASP_TDMTX_EN3 0x14 /* ASP1 TDM TX Enable 3 */ +#define CS53L30_ASP_TDMTX_EN4 0x15 /* ASP1 TDM TX Enable 4 */ +#define CS53L30_ASP_TDMTX_EN5 0x16 /* ASP1 TDM TX Enable 5 */ +#define CS53L30_ASP_TDMTX_EN6 0x17 /* ASP1 TDM TX Enable 6 */ +#define CS53L30_ASP_CTL2 0x18 /* ASP2 Control. */ +#define CS53L30_SFT_RAMP 0x1A /* Soft Ramp Control. */ +#define CS53L30_LRCK_CTL1 0x1B /* LRCK Control 1. */ +#define CS53L30_LRCK_CTL2 0x1C /* LRCK Control 2. */ +#define CS53L30_MUTEP_CTL1 0x1F /* Mute Pin Control 1. */ +#define CS53L30_MUTEP_CTL2 0x20 /* Mute Pin Control 2. */ +#define CS53L30_INBIAS_CTL1 0x21 /* Input Bias Control 1. */ +#define CS53L30_INBIAS_CTL2 0x22 /* Input Bias Control 2. */ +#define CS53L30_DMIC1_STR_CTL 0x23 /* DMIC1 Stereo Control. */ +#define CS53L30_DMIC2_STR_CTL 0x24 /* DMIC2 Stereo Control. */ +#define CS53L30_ADCDMIC1_CTL1 0x25 /* ADC1/DMIC1 Control 1. */ +#define CS53L30_ADCDMIC1_CTL2 0x26 /* ADC1/DMIC1 Control 2. */ +#define CS53L30_ADC1_CTL3 0x27 /* ADC1 Control 3. */ +#define CS53L30_ADC1_NG_CTL 0x28 /* ADC1 Noise Gate Control. */ +#define CS53L30_ADC1A_AFE_CTL 0x29 /* ADC1A AFE Control. */ +#define CS53L30_ADC1B_AFE_CTL 0x2A /* ADC1B AFE Control. */ +#define CS53L30_ADC1A_DIG_VOL 0x2B /* ADC1A Digital Volume. */ +#define CS53L30_ADC1B_DIG_VOL 0x2C /* ADC1B Digital Volume. */ +#define CS53L30_ADCDMIC2_CTL1 0x2D /* ADC2/DMIC2 Control 1. */ +#define CS53L30_ADCDMIC2_CTL2 0x2E /* ADC2/DMIC2 Control 2. */ +#define CS53L30_ADC2_CTL3 0x2F /* ADC2 Control 3. */ +#define CS53L30_ADC2_NG_CTL 0x30 /* ADC2 Noise Gate Control. */ +#define CS53L30_ADC2A_AFE_CTL 0x31 /* ADC2A AFE Control. */ +#define CS53L30_ADC2B_AFE_CTL 0x32 /* ADC2B AFE Control. */ +#define CS53L30_ADC2A_DIG_VOL 0x33 /* ADC2A Digital Volume. */ +#define CS53L30_ADC2B_DIG_VOL 0x34 /* ADC2B Digital Volume. */ +#define CS53L30_INT_MASK 0x35 /* Interrupt Mask. */ +#define CS53L30_IS 0x36 /* Interrupt Status. */ +#define CS53L30_MAX_REGISTER 0x36 + +#define CS53L30_TDM_SLOT_MAX 4 +#define CS53L30_ASP_TDMTX_CTL(x) (CS53L30_ASP_TDMTX_CTL1 + (x)) +/* x : index for registers; n : index for slot; 8 slots per register */ +#define CS53L30_ASP_TDMTX_ENx(x) (CS53L30_ASP_TDMTX_EN6 - (x)) +#define CS53L30_ASP_TDMTX_ENn(n) CS53L30_ASP_TDMTX_ENx((n) >> 3) +#define CS53L30_ASP_TDMTX_ENx_MAX 6 + +/* Device ID */ +#define CS53L30_DEVID 0x53A30 + +/* PDN_DONE Poll Maximum + * If soft ramp is set it will take much longer to power down + * the system. + */ +#define CS53L30_PDN_POLL_MAX 90 + +/* Bitfield Definitions */ + +/* R6 (0x06) CS53L30_PWRCTL - Power Control */ +#define CS53L30_PDN_ULP_SHIFT 7 +#define CS53L30_PDN_ULP_MASK (1 << CS53L30_PDN_ULP_SHIFT) +#define CS53L30_PDN_ULP (1 << CS53L30_PDN_ULP_SHIFT) +#define CS53L30_PDN_LP_SHIFT 6 +#define CS53L30_PDN_LP_MASK (1 << CS53L30_PDN_LP_SHIFT) +#define CS53L30_PDN_LP (1 << CS53L30_PDN_LP_SHIFT) +#define CS53L30_DISCHARGE_FILT_SHIFT 5 +#define CS53L30_DISCHARGE_FILT_MASK (1 << CS53L30_DISCHARGE_FILT_SHIFT) +#define CS53L30_DISCHARGE_FILT (1 << CS53L30_DISCHARGE_FILT_SHIFT) +#define CS53L30_THMS_PDN_SHIFT 4 +#define CS53L30_THMS_PDN_MASK (1 << CS53L30_THMS_PDN_SHIFT) +#define CS53L30_THMS_PDN (1 << CS53L30_THMS_PDN_SHIFT) + +#define CS53L30_PWRCTL_DEFAULT (CS53L30_THMS_PDN) + +/* R7 (0x07) CS53L30_MCLKCTL - MCLK Control */ +#define CS53L30_MCLK_DIS_SHIFT 7 +#define CS53L30_MCLK_DIS_MASK (1 << CS53L30_MCLK_DIS_SHIFT) +#define CS53L30_MCLK_DIS (1 << CS53L30_MCLK_DIS_SHIFT) +#define CS53L30_MCLK_INT_SCALE_SHIFT 6 +#define CS53L30_MCLK_INT_SCALE_MASK (1 << CS53L30_MCLK_INT_SCALE_SHIFT) +#define CS53L30_MCLK_INT_SCALE (1 << CS53L30_MCLK_INT_SCALE_SHIFT) +#define CS53L30_DMIC_DRIVE_SHIFT 5 +#define CS53L30_DMIC_DRIVE_MASK (1 << CS53L30_DMIC_DRIVE_SHIFT) +#define CS53L30_DMIC_DRIVE (1 << CS53L30_DMIC_DRIVE_SHIFT) +#define CS53L30_MCLK_DIV_SHIFT 2 +#define CS53L30_MCLK_DIV_WIDTH 2 +#define CS53L30_MCLK_DIV_MASK (((1 << CS53L30_MCLK_DIV_WIDTH) - 1) << CS53L30_MCLK_DIV_SHIFT) +#define CS53L30_MCLK_DIV_BY_1 (0x0 << CS53L30_MCLK_DIV_SHIFT) +#define CS53L30_MCLK_DIV_BY_2 (0x1 << CS53L30_MCLK_DIV_SHIFT) +#define CS53L30_MCLK_DIV_BY_3 (0x2 << CS53L30_MCLK_DIV_SHIFT) +#define CS53L30_SYNC_EN_SHIFT 1 +#define CS53L30_SYNC_EN_MASK (1 << CS53L30_SYNC_EN_SHIFT) +#define CS53L30_SYNC_EN (1 << CS53L30_SYNC_EN_SHIFT) + +#define CS53L30_MCLKCTL_DEFAULT (CS53L30_MCLK_DIV_BY_2) + +/* R8 (0x08) CS53L30_INT_SR_CTL - Internal Sample Rate Control */ +#define CS53L30_INTRNL_FS_RATIO_SHIFT 4 +#define CS53L30_INTRNL_FS_RATIO_MASK (1 << CS53L30_INTRNL_FS_RATIO_SHIFT) +#define CS53L30_INTRNL_FS_RATIO (1 << CS53L30_INTRNL_FS_RATIO_SHIFT) +#define CS53L30_MCLK_19MHZ_EN_SHIFT 0 +#define CS53L30_MCLK_19MHZ_EN_MASK (1 << CS53L30_MCLK_19MHZ_EN_SHIFT) +#define CS53L30_MCLK_19MHZ_EN (1 << CS53L30_MCLK_19MHZ_EN_SHIFT) + +/* 0x6 << 1 is reserved bits */ +#define CS53L30_INT_SR_CTL_DEFAULT (CS53L30_INTRNL_FS_RATIO | 0x6 << 1) + +/* R10 (0x0A) CS53L30_MICBIAS_CTL - Mic Bias Control */ +#define CS53L30_MIC4_BIAS_PDN_SHIFT 7 +#define CS53L30_MIC4_BIAS_PDN_MASK (1 << CS53L30_MIC4_BIAS_PDN_SHIFT) +#define CS53L30_MIC4_BIAS_PDN (1 << CS53L30_MIC4_BIAS_PDN_SHIFT) +#define CS53L30_MIC3_BIAS_PDN_SHIFT 6 +#define CS53L30_MIC3_BIAS_PDN_MASK (1 << CS53L30_MIC3_BIAS_PDN_SHIFT) +#define CS53L30_MIC3_BIAS_PDN (1 << CS53L30_MIC3_BIAS_PDN_SHIFT) +#define CS53L30_MIC2_BIAS_PDN_SHIFT 5 +#define CS53L30_MIC2_BIAS_PDN_MASK (1 << CS53L30_MIC2_BIAS_PDN_SHIFT) +#define CS53L30_MIC2_BIAS_PDN (1 << CS53L30_MIC2_BIAS_PDN_SHIFT) +#define CS53L30_MIC1_BIAS_PDN_SHIFT 4 +#define CS53L30_MIC1_BIAS_PDN_MASK (1 << CS53L30_MIC1_BIAS_PDN_SHIFT) +#define CS53L30_MIC1_BIAS_PDN (1 << CS53L30_MIC1_BIAS_PDN_SHIFT) +#define CS53L30_MICx_BIAS_PDN (0xf << CS53L30_MIC1_BIAS_PDN_SHIFT) +#define CS53L30_VP_MIN_SHIFT 2 +#define CS53L30_VP_MIN_MASK (1 << CS53L30_VP_MIN_SHIFT) +#define CS53L30_VP_MIN (1 << CS53L30_VP_MIN_SHIFT) +#define CS53L30_MIC_BIAS_CTRL_SHIFT 0 +#define CS53L30_MIC_BIAS_CTRL_WIDTH 2 +#define CS53L30_MIC_BIAS_CTRL_MASK (((1 << CS53L30_MIC_BIAS_CTRL_WIDTH) - 1) << CS53L30_MIC_BIAS_CTRL_SHIFT) +#define CS53L30_MIC_BIAS_CTRL_HIZ (0 << CS53L30_MIC_BIAS_CTRL_SHIFT) +#define CS53L30_MIC_BIAS_CTRL_1V8 (1 << CS53L30_MIC_BIAS_CTRL_SHIFT) +#define CS53L30_MIC_BIAS_CTRL_2V75 (2 << CS53L30_MIC_BIAS_CTRL_SHIFT) + +#define CS53L30_MICBIAS_CTL_DEFAULT (CS53L30_MICx_BIAS_PDN | CS53L30_VP_MIN) + +/* R12 (0x0C) CS53L30_ASPCFG_CTL - ASP Configuration Control */ +#define CS53L30_ASP_MS_SHIFT 7 +#define CS53L30_ASP_MS_MASK (1 << CS53L30_ASP_MS_SHIFT) +#define CS53L30_ASP_MS (1 << CS53L30_ASP_MS_SHIFT) +#define CS53L30_ASP_SCLK_INV_SHIFT 4 +#define CS53L30_ASP_SCLK_INV_MASK (1 << CS53L30_ASP_SCLK_INV_SHIFT) +#define CS53L30_ASP_SCLK_INV (1 << CS53L30_ASP_SCLK_INV_SHIFT) +#define CS53L30_ASP_RATE_SHIFT 0 +#define CS53L30_ASP_RATE_WIDTH 4 +#define CS53L30_ASP_RATE_MASK (((1 << CS53L30_ASP_RATE_WIDTH) - 1) << CS53L30_ASP_RATE_SHIFT) +#define CS53L30_ASP_RATE_48K (0xc << CS53L30_ASP_RATE_SHIFT) + +#define CS53L30_ASPCFG_CTL_DEFAULT (CS53L30_ASP_RATE_48K) + +/* R13/R24 (0x0D/0x18) CS53L30_ASP_CTL1 & CS53L30_ASP_CTL2 - ASP Control 1~2 */ +#define CS53L30_ASP_TDM_PDN_SHIFT 7 +#define CS53L30_ASP_TDM_PDN_MASK (1 << CS53L30_ASP_TDM_PDN_SHIFT) +#define CS53L30_ASP_TDM_PDN (1 << CS53L30_ASP_TDM_PDN_SHIFT) +#define CS53L30_ASP_SDOUTx_PDN_SHIFT 6 +#define CS53L30_ASP_SDOUTx_PDN_MASK (1 << CS53L30_ASP_SDOUTx_PDN_SHIFT) +#define CS53L30_ASP_SDOUTx_PDN (1 << CS53L30_ASP_SDOUTx_PDN_SHIFT) +#define CS53L30_ASP_3ST_SHIFT 5 +#define CS53L30_ASP_3ST_MASK (1 << CS53L30_ASP_3ST_SHIFT) +#define CS53L30_ASP_3ST (1 << CS53L30_ASP_3ST_SHIFT) +#define CS53L30_SHIFT_LEFT_SHIFT 4 +#define CS53L30_SHIFT_LEFT_MASK (1 << CS53L30_SHIFT_LEFT_SHIFT) +#define CS53L30_SHIFT_LEFT (1 << CS53L30_SHIFT_LEFT_SHIFT) +#define CS53L30_ASP_SDOUTx_DRIVE_SHIFT 0 +#define CS53L30_ASP_SDOUTx_DRIVE_MASK (1 << CS53L30_ASP_SDOUTx_DRIVE_SHIFT) +#define CS53L30_ASP_SDOUTx_DRIVE (1 << CS53L30_ASP_SDOUTx_DRIVE_SHIFT) + +#define CS53L30_ASP_CTL1_DEFAULT (CS53L30_ASP_TDM_PDN) +#define CS53L30_ASP_CTL2_DEFAULT (0) + +/* R14 (0x0E) ~ R17 (0x11) CS53L30_ASP_TDMTX_CTLx - ASP TDM TX Control 1~4 */ +#define CS53L30_ASP_CHx_TX_STATE_SHIFT 7 +#define CS53L30_ASP_CHx_TX_STATE_MASK (1 << CS53L30_ASP_CHx_TX_STATE_SHIFT) +#define CS53L30_ASP_CHx_TX_STATE (1 << CS53L30_ASP_CHx_TX_STATE_SHIFT) +#define CS53L30_ASP_CHx_TX_LOC_SHIFT 0 +#define CS53L30_ASP_CHx_TX_LOC_WIDTH 6 +#define CS53L30_ASP_CHx_TX_LOC_MASK (((1 << CS53L30_ASP_CHx_TX_LOC_WIDTH) - 1) << CS53L30_ASP_CHx_TX_LOC_SHIFT) +#define CS53L30_ASP_CHx_TX_LOC_MAX (47 << CS53L30_ASP_CHx_TX_LOC_SHIFT) +#define CS53L30_ASP_CHx_TX_LOC(x) ((x) << CS53L30_ASP_CHx_TX_LOC_SHIFT) + +#define CS53L30_ASP_TDMTX_CTLx_DEFAULT (CS53L30_ASP_CHx_TX_LOC_MAX) + +/* R18 (0x12) ~ R23 (0x17) CS53L30_ASP_TDMTX_ENx - ASP TDM TX Enable 1~6 */ +#define CS53L30_ASP_TDMTX_ENx_DEFAULT (0) + +/* R26 (0x1A) CS53L30_SFT_RAMP - Soft Ramp Control */ +#define CS53L30_DIGSFT_SHIFT 5 +#define CS53L30_DIGSFT_MASK (1 << CS53L30_DIGSFT_SHIFT) +#define CS53L30_DIGSFT (1 << CS53L30_DIGSFT_SHIFT) + +#define CS53L30_SFT_RMP_DEFAULT (0) + +/* R28 (0x1C) CS53L30_LRCK_CTL2 - LRCK Control 2 */ +#define CS53L30_LRCK_50_NPW_SHIFT 3 +#define CS53L30_LRCK_50_NPW_MASK (1 << CS53L30_LRCK_50_NPW_SHIFT) +#define CS53L30_LRCK_50_NPW (1 << CS53L30_LRCK_50_NPW_SHIFT) +#define CS53L30_LRCK_TPWH_SHIFT 0 +#define CS53L30_LRCK_TPWH_WIDTH 3 +#define CS53L30_LRCK_TPWH_MASK (((1 << CS53L30_LRCK_TPWH_WIDTH) - 1) << CS53L30_LRCK_TPWH_SHIFT) +#define CS53L30_LRCK_TPWH(x) (((x) << CS53L30_LRCK_TPWH_SHIFT) & CS53L30_LRCK_TPWH_MASK) + +#define CS53L30_LRCK_CTLx_DEFAULT (0) + +/* R31 (0x1F) CS53L30_MUTEP_CTL1 - MUTE Pin Control 1 */ +#define CS53L30_MUTE_PDN_ULP_SHIFT 7 +#define CS53L30_MUTE_PDN_ULP_MASK (1 << CS53L30_MUTE_PDN_ULP_SHIFT) +#define CS53L30_MUTE_PDN_ULP (1 << CS53L30_MUTE_PDN_ULP_SHIFT) +#define CS53L30_MUTE_PDN_LP_SHIFT 6 +#define CS53L30_MUTE_PDN_LP_MASK (1 << CS53L30_MUTE_PDN_LP_SHIFT) +#define CS53L30_MUTE_PDN_LP (1 << CS53L30_MUTE_PDN_LP_SHIFT) +#define CS53L30_MUTE_M4B_PDN_SHIFT 4 +#define CS53L30_MUTE_M4B_PDN_MASK (1 << CS53L30_MUTE_M4B_PDN_SHIFT) +#define CS53L30_MUTE_M4B_PDN (1 << CS53L30_MUTE_M4B_PDN_SHIFT) +#define CS53L30_MUTE_M3B_PDN_SHIFT 3 +#define CS53L30_MUTE_M3B_PDN_MASK (1 << CS53L30_MUTE_M3B_PDN_SHIFT) +#define CS53L30_MUTE_M3B_PDN (1 << CS53L30_MUTE_M3B_PDN_SHIFT) +#define CS53L30_MUTE_M2B_PDN_SHIFT 2 +#define CS53L30_MUTE_M2B_PDN_MASK (1 << CS53L30_MUTE_M2B_PDN_SHIFT) +#define CS53L30_MUTE_M2B_PDN (1 << CS53L30_MUTE_M2B_PDN_SHIFT) +#define CS53L30_MUTE_M1B_PDN_SHIFT 1 +#define CS53L30_MUTE_M1B_PDN_MASK (1 << CS53L30_MUTE_M1B_PDN_SHIFT) +#define CS53L30_MUTE_M1B_PDN (1 << CS53L30_MUTE_M1B_PDN_SHIFT) +/* Note: be careful - x starts from 0 */ +#define CS53L30_MUTE_MxB_PDN_SHIFT(x) (CS53L30_MUTE_M1B_PDN_SHIFT + (x)) +#define CS53L30_MUTE_MxB_PDN_MASK(x) (1 << CS53L30_MUTE_MxB_PDN_SHIFT(x)) +#define CS53L30_MUTE_MxB_PDN(x) (1 << CS53L30_MUTE_MxB_PDN_SHIFT(x)) +#define CS53L30_MUTE_MB_ALL_PDN_SHIFT 0 +#define CS53L30_MUTE_MB_ALL_PDN_MASK (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) +#define CS53L30_MUTE_MB_ALL_PDN (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) + +#define CS53L30_MUTEP_CTL1_DEFAULT (0) + +/* R32 (0x20) CS53L30_MUTEP_CTL2 - MUTE Pin Control 2 */ +#define CS53L30_MUTE_PIN_POLARITY_SHIFT 7 +#define CS53L30_MUTE_PIN_POLARITY_MASK (1 << CS53L30_MUTE_PIN_POLARITY_SHIFT) +#define CS53L30_MUTE_PIN_POLARITY (1 << CS53L30_MUTE_PIN_POLARITY_SHIFT) +#define CS53L30_MUTE_ASP_TDM_PDN_SHIFT 6 +#define CS53L30_MUTE_ASP_TDM_PDN_MASK (1 << CS53L30_MUTE_ASP_TDM_PDN_SHIFT) +#define CS53L30_MUTE_ASP_TDM_PDN (1 << CS53L30_MUTE_ASP_TDM_PDN_SHIFT) +#define CS53L30_MUTE_ASP_SDOUT2_PDN_SHIFT 5 +#define CS53L30_MUTE_ASP_SDOUT2_PDN_MASK (1 << CS53L30_MUTE_ASP_SDOUT2_PDN_SHIFT) +#define CS53L30_MUTE_ASP_SDOUT2_PDN (1 << CS53L30_MUTE_ASP_SDOUT2_PDN_SHIFT) +#define CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT 4 +#define CS53L30_MUTE_ASP_SDOUT1_PDN_MASK (1 << CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT) +#define CS53L30_MUTE_ASP_SDOUT1_PDN (1 << CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT) +/* Note: be careful - x starts from 0 */ +#define CS53L30_MUTE_ASP_SDOUTx_PDN_SHIFT(x) ((x) + CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT) +#define CS53L30_MUTE_ASP_SDOUTx_PDN_MASK(x) (1 << CS53L30_MUTE_ASP_SDOUTx_PDN_SHIFT(x)) +#define CS53L30_MUTE_ASP_SDOUTx_PDN (1 << CS53L30_MUTE_ASP_SDOUTx_PDN_SHIFT(x)) +#define CS53L30_MUTE_ADC2B_PDN_SHIFT 3 +#define CS53L30_MUTE_ADC2B_PDN_MASK (1 << CS53L30_MUTE_ADC2B_PDN_SHIFT) +#define CS53L30_MUTE_ADC2B_PDN (1 << CS53L30_MUTE_ADC2B_PDN_SHIFT) +#define CS53L30_MUTE_ADC2A_PDN_SHIFT 2 +#define CS53L30_MUTE_ADC2A_PDN_MASK (1 << CS53L30_MUTE_ADC2A_PDN_SHIFT) +#define CS53L30_MUTE_ADC2A_PDN (1 << CS53L30_MUTE_ADC2A_PDN_SHIFT) +#define CS53L30_MUTE_ADC1B_PDN_SHIFT 1 +#define CS53L30_MUTE_ADC1B_PDN_MASK (1 << CS53L30_MUTE_ADC1B_PDN_SHIFT) +#define CS53L30_MUTE_ADC1B_PDN (1 << CS53L30_MUTE_ADC1B_PDN_SHIFT) +#define CS53L30_MUTE_ADC1A_PDN_SHIFT 0 +#define CS53L30_MUTE_ADC1A_PDN_MASK (1 << CS53L30_MUTE_ADC1A_PDN_SHIFT) +#define CS53L30_MUTE_ADC1A_PDN (1 << CS53L30_MUTE_ADC1A_PDN_SHIFT) + +#define CS53L30_MUTEP_CTL2_DEFAULT (CS53L30_MUTE_PIN_POLARITY) + +/* R33 (0x21) CS53L30_INBIAS_CTL1 - Input Bias Control 1 */ +#define CS53L30_IN4M_BIAS_SHIFT 6 +#define CS53L30_IN4M_BIAS_WIDTH 2 +#define CS53L30_IN4M_BIAS_MASK (((1 << CS53L30_IN4M_BIAS_WIDTH) - 1) << CS53L30_IN4M_BIAS_SHIFT) +#define CS53L30_IN4M_BIAS_OPEN (0 << CS53L30_IN4M_BIAS_SHIFT) +#define CS53L30_IN4M_BIAS_PULL_DOWN (1 << CS53L30_IN4M_BIAS_SHIFT) +#define CS53L30_IN4M_BIAS_VCM (2 << CS53L30_IN4M_BIAS_SHIFT) +#define CS53L30_IN4P_BIAS_SHIFT 4 +#define CS53L30_IN4P_BIAS_WIDTH 2 +#define CS53L30_IN4P_BIAS_MASK (((1 << CS53L30_IN4P_BIAS_WIDTH) - 1) << CS53L30_IN4P_BIAS_SHIFT) +#define CS53L30_IN4P_BIAS_OPEN (0 << CS53L30_IN4P_BIAS_SHIFT) +#define CS53L30_IN4P_BIAS_PULL_DOWN (1 << CS53L30_IN4P_BIAS_SHIFT) +#define CS53L30_IN4P_BIAS_VCM (2 << CS53L30_IN4P_BIAS_SHIFT) +#define CS53L30_IN3M_BIAS_SHIFT 2 +#define CS53L30_IN3M_BIAS_WIDTH 2 +#define CS53L30_IN3M_BIAS_MASK (((1 << CS53L30_IN3M_BIAS_WIDTH) - 1) << CS53L30_IN4M_BIAS_SHIFT) +#define CS53L30_IN3M_BIAS_OPEN (0 << CS53L30_IN3M_BIAS_SHIFT) +#define CS53L30_IN3M_BIAS_PULL_DOWN (1 << CS53L30_IN3M_BIAS_SHIFT) +#define CS53L30_IN3M_BIAS_VCM (2 << CS53L30_IN3M_BIAS_SHIFT) +#define CS53L30_IN3P_BIAS_SHIFT 0 +#define CS53L30_IN3P_BIAS_WIDTH 2 +#define CS53L30_IN3P_BIAS_MASK (((1 << CS53L30_IN3P_BIAS_WIDTH) - 1) << CS53L30_IN3P_BIAS_SHIFT) +#define CS53L30_IN3P_BIAS_OPEN (0 << CS53L30_IN3P_BIAS_SHIFT) +#define CS53L30_IN3P_BIAS_PULL_DOWN (1 << CS53L30_IN3P_BIAS_SHIFT) +#define CS53L30_IN3P_BIAS_VCM (2 << CS53L30_IN3P_BIAS_SHIFT) + +#define CS53L30_INBIAS_CTL1_DEFAULT (CS53L30_IN4M_BIAS_VCM | CS53L30_IN4P_BIAS_VCM |\ + CS53L30_IN3M_BIAS_VCM | CS53L30_IN3P_BIAS_VCM) + +/* R34 (0x22) CS53L30_INBIAS_CTL2 - Input Bias Control 2 */ +#define CS53L30_IN2M_BIAS_SHIFT 6 +#define CS53L30_IN2M_BIAS_WIDTH 2 +#define CS53L30_IN2M_BIAS_MASK (((1 << CS53L30_IN2M_BIAS_WIDTH) - 1) << CS53L30_IN2M_BIAS_SHIFT) +#define CS53L30_IN2M_BIAS_OPEN (0 << CS53L30_IN2M_BIAS_SHIFT) +#define CS53L30_IN2M_BIAS_PULL_DOWN (1 << CS53L30_IN2M_BIAS_SHIFT) +#define CS53L30_IN2M_BIAS_VCM (2 << CS53L30_IN2M_BIAS_SHIFT) +#define CS53L30_IN2P_BIAS_SHIFT 4 +#define CS53L30_IN2P_BIAS_WIDTH 2 +#define CS53L30_IN2P_BIAS_MASK (((1 << CS53L30_IN2P_BIAS_WIDTH) - 1) << CS53L30_IN2P_BIAS_SHIFT) +#define CS53L30_IN2P_BIAS_OPEN (0 << CS53L30_IN2P_BIAS_SHIFT) +#define CS53L30_IN2P_BIAS_PULL_DOWN (1 << CS53L30_IN2P_BIAS_SHIFT) +#define CS53L30_IN2P_BIAS_VCM (2 << CS53L30_IN2P_BIAS_SHIFT) +#define CS53L30_IN1M_BIAS_SHIFT 2 +#define CS53L30_IN1M_BIAS_WIDTH 2 +#define CS53L30_IN1M_BIAS_MASK (((1 << CS53L30_IN1M_BIAS_WIDTH) - 1) << CS53L30_IN1M_BIAS_SHIFT) +#define CS53L30_IN1M_BIAS_OPEN (0 << CS53L30_IN1M_BIAS_SHIFT) +#define CS53L30_IN1M_BIAS_PULL_DOWN (1 << CS53L30_IN1M_BIAS_SHIFT) +#define CS53L30_IN1M_BIAS_VCM (2 << CS53L30_IN1M_BIAS_SHIFT) +#define CS53L30_IN1P_BIAS_SHIFT 0 +#define CS53L30_IN1P_BIAS_WIDTH 2 +#define CS53L30_IN1P_BIAS_MASK (((1 << CS53L30_IN1P_BIAS_WIDTH) - 1) << CS53L30_IN1P_BIAS_SHIFT) +#define CS53L30_IN1P_BIAS_OPEN (0 << CS53L30_IN1P_BIAS_SHIFT) +#define CS53L30_IN1P_BIAS_PULL_DOWN (1 << CS53L30_IN1P_BIAS_SHIFT) +#define CS53L30_IN1P_BIAS_VCM (2 << CS53L30_IN1P_BIAS_SHIFT) + +#define CS53L30_INBIAS_CTL2_DEFAULT (CS53L30_IN2M_BIAS_VCM | CS53L30_IN2P_BIAS_VCM |\ + CS53L30_IN1M_BIAS_VCM | CS53L30_IN1P_BIAS_VCM) + +/* R35 (0x23) & R36 (0x24) CS53L30_DMICx_STR_CTL - DMIC1 & DMIC2 Stereo Control */ +#define CS53L30_DMICx_STEREO_ENB_SHIFT 5 +#define CS53L30_DMICx_STEREO_ENB_MASK (1 << CS53L30_DMICx_STEREO_ENB_SHIFT) +#define CS53L30_DMICx_STEREO_ENB (1 << CS53L30_DMICx_STEREO_ENB_SHIFT) + +/* 0x88 and 0xCC are reserved bits */ +#define CS53L30_DMIC1_STR_CTL_DEFAULT (CS53L30_DMICx_STEREO_ENB | 0x88) +#define CS53L30_DMIC2_STR_CTL_DEFAULT (CS53L30_DMICx_STEREO_ENB | 0xCC) + +/* R37/R45 (0x25/0x2D) CS53L30_ADCDMICx_CTL1 - ADC1/DMIC1 & ADC2/DMIC2 Control 1 */ +#define CS53L30_ADCxB_PDN_SHIFT 7 +#define CS53L30_ADCxB_PDN_MASK (1 << CS53L30_ADCxB_PDN_SHIFT) +#define CS53L30_ADCxB_PDN (1 << CS53L30_ADCxB_PDN_SHIFT) +#define CS53L30_ADCxA_PDN_SHIFT 6 +#define CS53L30_ADCxA_PDN_MASK (1 << CS53L30_ADCxA_PDN_SHIFT) +#define CS53L30_ADCxA_PDN (1 << CS53L30_ADCxA_PDN_SHIFT) +#define CS53L30_DMICx_PDN_SHIFT 2 +#define CS53L30_DMICx_PDN_MASK (1 << CS53L30_DMICx_PDN_SHIFT) +#define CS53L30_DMICx_PDN (1 << CS53L30_DMICx_PDN_SHIFT) +#define CS53L30_DMICx_SCLK_DIV_SHIFT 1 +#define CS53L30_DMICx_SCLK_DIV_MASK (1 << CS53L30_DMICx_SCLK_DIV_SHIFT) +#define CS53L30_DMICx_SCLK_DIV (1 << CS53L30_DMICx_SCLK_DIV_SHIFT) +#define CS53L30_CH_TYPE_SHIFT 0 +#define CS53L30_CH_TYPE_MASK (1 << CS53L30_CH_TYPE_SHIFT) +#define CS53L30_CH_TYPE (1 << CS53L30_CH_TYPE_SHIFT) + +#define CS53L30_ADCDMICx_PDN_MASK 0xFF +#define CS53L30_ADCDMICx_CTL1_DEFAULT (CS53L30_DMICx_PDN) + +/* R38/R46 (0x26/0x2E) CS53L30_ADCDMICx_CTL2 - ADC1/DMIC1 & ADC2/DMIC2 Control 2 */ +#define CS53L30_ADCx_NOTCH_DIS_SHIFT 7 +#define CS53L30_ADCx_NOTCH_DIS_MASK (1 << CS53L30_ADCx_NOTCH_DIS_SHIFT) +#define CS53L30_ADCx_NOTCH_DIS (1 << CS53L30_ADCx_NOTCH_DIS_SHIFT) +#define CS53L30_ADCxB_INV_SHIFT 5 +#define CS53L30_ADCxB_INV_MASK (1 << CS53L30_ADCxB_INV_SHIFT) +#define CS53L30_ADCxB_INV (1 << CS53L30_ADCxB_INV_SHIFT) +#define CS53L30_ADCxA_INV_SHIFT 4 +#define CS53L30_ADCxA_INV_MASK (1 << CS53L30_ADCxA_INV_SHIFT) +#define CS53L30_ADCxA_INV (1 << CS53L30_ADCxA_INV_SHIFT) +#define CS53L30_ADCxB_DIG_BOOST_SHIFT 1 +#define CS53L30_ADCxB_DIG_BOOST_MASK (1 << CS53L30_ADCxB_DIG_BOOST_SHIFT) +#define CS53L30_ADCxB_DIG_BOOST (1 << CS53L30_ADCxB_DIG_BOOST_SHIFT) +#define CS53L30_ADCxA_DIG_BOOST_SHIFT 0 +#define CS53L30_ADCxA_DIG_BOOST_MASK (1 << CS53L30_ADCxA_DIG_BOOST_SHIFT) +#define CS53L30_ADCxA_DIG_BOOST (1 << CS53L30_ADCxA_DIG_BOOST_SHIFT) + +#define CS53L30_ADCDMIC1_CTL2_DEFAULT (0) + +/* R39/R47 (0x27/0x2F) CS53L30_ADCx_CTL3 - ADC1/ADC2 Control 3 */ +#define CS53L30_ADCx_HPF_EN_SHIFT 3 +#define CS53L30_ADCx_HPF_EN_MASK (1 << CS53L30_ADCx_HPF_EN_SHIFT) +#define CS53L30_ADCx_HPF_EN (1 << CS53L30_ADCx_HPF_EN_SHIFT) +#define CS53L30_ADCx_HPF_CF_SHIFT 1 +#define CS53L30_ADCx_HPF_CF_WIDTH 2 +#define CS53L30_ADCx_HPF_CF_MASK (((1 << CS53L30_ADCx_HPF_CF_WIDTH) - 1) << CS53L30_ADCx_HPF_CF_SHIFT) +#define CS53L30_ADCx_HPF_CF_1HZ86 (0 << CS53L30_ADCx_HPF_CF_SHIFT) +#define CS53L30_ADCx_HPF_CF_120HZ (1 << CS53L30_ADCx_HPF_CF_SHIFT) +#define CS53L30_ADCx_HPF_CF_235HZ (2 << CS53L30_ADCx_HPF_CF_SHIFT) +#define CS53L30_ADCx_HPF_CF_466HZ (3 << CS53L30_ADCx_HPF_CF_SHIFT) +#define CS53L30_ADCx_NG_ALL_SHIFT 0 +#define CS53L30_ADCx_NG_ALL_MASK (1 << CS53L30_ADCx_NG_ALL_SHIFT) +#define CS53L30_ADCx_NG_ALL (1 << CS53L30_ADCx_NG_ALL_SHIFT) + +#define CS53L30_ADCx_CTL3_DEFAULT (CS53L30_ADCx_HPF_EN) + +/* R40/R48 (0x28/0x30) CS53L30_ADCx_NG_CTL - ADC1/ADC2 Noise Gate Control */ +#define CS53L30_ADCxB_NG_SHIFT 7 +#define CS53L30_ADCxB_NG_MASK (1 << CS53L30_ADCxB_NG_SHIFT) +#define CS53L30_ADCxB_NG (1 << CS53L30_ADCxB_NG_SHIFT) +#define CS53L30_ADCxA_NG_SHIFT 6 +#define CS53L30_ADCxA_NG_MASK (1 << CS53L30_ADCxA_NG_SHIFT) +#define CS53L30_ADCxA_NG (1 << CS53L30_ADCxA_NG_SHIFT) +#define CS53L30_ADCx_NG_BOOST_SHIFT 5 +#define CS53L30_ADCx_NG_BOOST_MASK (1 << CS53L30_ADCx_NG_BOOST_SHIFT) +#define CS53L30_ADCx_NG_BOOST (1 << CS53L30_ADCx_NG_BOOST_SHIFT) +#define CS53L30_ADCx_NG_THRESH_SHIFT 2 +#define CS53L30_ADCx_NG_THRESH_WIDTH 3 +#define CS53L30_ADCx_NG_THRESH_MASK (((1 << CS53L30_ADCx_NG_THRESH_WIDTH) - 1) << CS53L30_ADCx_NG_THRESH_SHIFT) +#define CS53L30_ADCx_NG_DELAY_SHIFT 0 +#define CS53L30_ADCx_NG_DELAY_WIDTH 2 +#define CS53L30_ADCx_NG_DELAY_MASK (((1 << CS53L30_ADCx_NG_DELAY_WIDTH) - 1) << CS53L30_ADCx_NG_DELAY_SHIFT) + +#define CS53L30_ADCx_NG_CTL_DEFAULT (0) + +/* R41/R42/R49/R50 (0x29/0x2A/0x31/0x32) CS53L30_ADCxy_AFE_CTL - ADC1A/1B/2A/2B AFE Control */ +#define CS53L30_ADCxy_PREAMP_SHIFT 6 +#define CS53L30_ADCxy_PREAMP_WIDTH 2 +#define CS53L30_ADCxy_PREAMP_MASK (((1 << CS53L30_ADCxy_PREAMP_WIDTH) - 1) << CS53L30_ADCxy_PREAMP_SHIFT) +#define CS53L30_ADCxy_PGA_VOL_SHIFT 0 +#define CS53L30_ADCxy_PGA_VOL_WIDTH 6 +#define CS53L30_ADCxy_PGA_VOL_MASK (((1 << CS53L30_ADCxy_PGA_VOL_WIDTH) - 1) << CS53L30_ADCxy_PGA_VOL_SHIFT) + +#define CS53L30_ADCxy_AFE_CTL_DEFAULT (0) + +/* R43/R44/R51/R52 (0x2B/0x2C/0x33/0x34) CS53L30_ADCxy_DIG_VOL - ADC1A/1B/2A/2B Digital Volume */ +#define CS53L30_ADCxy_VOL_MUTE (0x80) + +#define CS53L30_ADCxy_DIG_VOL_DEFAULT (0x0) + +/* CS53L30_INT */ +#define CS53L30_PDN_DONE (1 << 7) +#define CS53L30_THMS_TRIP (1 << 6) +#define CS53L30_SYNC_DONE (1 << 5) +#define CS53L30_ADC2B_OVFL (1 << 4) +#define CS53L30_ADC2A_OVFL (1 << 3) +#define CS53L30_ADC1B_OVFL (1 << 2) +#define CS53L30_ADC1A_OVFL (1 << 1) +#define CS53L30_MUTE_PIN (1 << 0) +#define CS53L30_DEVICE_INT_MASK 0xFF + +#endif /* __CS53L30_H__ */ -- cgit v1.3-14-g43fede From add3873ebdf375e0366044fa0c0078e402eef744 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 13:44:21 +0200 Subject: ASoC: dt: Fix typo Signed-off-by: Andrea Gelmini Signed-off-by: Mark Brown --- Documentation/sound/alsa/soc/machine.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/sound/alsa/soc/machine.txt b/Documentation/sound/alsa/soc/machine.txt index 74056dba52be..6bf2d2063b52 100644 --- a/Documentation/sound/alsa/soc/machine.txt +++ b/Documentation/sound/alsa/soc/machine.txt @@ -3,7 +3,7 @@ ASoC Machine Driver The ASoC machine (or board) driver is the code that glues together all the component drivers (e.g. codecs, platforms and DAIs). It also describes the -relationships between each componnent which include audio paths, GPIOs, +relationships between each component which include audio paths, GPIOs, interrupts, clocking, jacks and voltage regulators. The machine driver can contain codec and platform specific code. It registers -- cgit v1.3-14-g43fede From 6dca83fdee7c45a960018141827c9d4b5b50d0a2 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 13:39:54 +0200 Subject: ASoC: fsl: Fix typo Signed-off-by: Andrea Gelmini Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt index ceaef5126989..f749e2744824 100644 --- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt @@ -58,7 +58,7 @@ Required properties: * DMIC (stands for Digital Microphone Jack) Note: The "Mic Jack" and "AMIC" are redundant while - coexsiting in order to support the old bindings + coexisting in order to support the old bindings of wm8962 and sgtl5000. Optional properties: -- cgit v1.3-14-g43fede From e1f90fc2d2767145c64fad838e29d1a43abb4792 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sat, 14 May 2016 23:09:38 +0200 Subject: ASoC: max8960: add bindings for the max9860 codec This adds the device tree binding documentation for the Maxim Integrated MAX9860 mono audio voice codec. Acked-by: Rob Herring Signed-off-by: Peter Rosin Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/max9860.txt | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/max9860.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/max9860.txt b/Documentation/devicetree/bindings/sound/max9860.txt new file mode 100644 index 000000000000..e0d4e95e31b3 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max9860.txt @@ -0,0 +1,28 @@ +MAX9860 Mono Audio Voice Codec + +Required properties: + + - compatible : "maxim,max9860" + + - reg : the I2C address of the device + + - AVDD-supply, DVDD-supply and DVDDIO-supply : power supplies for + the device, as covered in bindings/regulator/regulator.txt + + - clock-names : Required element: "mclk". + + - clocks : A clock specifier for the clock connected as MCLK. + +Examples: + + max9860: max9860@10 { + compatible = "maxim,max9860"; + reg = <0x10>; + + AVDD-supply = <®_1v8>; + DVDD-supply = <®_1v8>; + DVDDIO-supply = <®_3v0>; + + clock-names = "mclk"; + clocks = <&pck2>; + }; -- cgit v1.3-14-g43fede From 65aca64d05b5eaa5ce15e18b458a8d338ddbd478 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 18 May 2016 16:46:36 +0300 Subject: ASoC: omap-mcpdm: Add support for pdmclk clock handling McPDM module receives it's functional clock from external source. This clock is the pdmclk provided by the twl6040 audio IC. If the clock is not available all register accesses to McPDM fails and the module is not operational. Signed-off-by: Peter Ujfalusi Acked-by: Rob Herring Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/omap-mcpdm.txt | 10 ++++++++++ sound/soc/omap/omap-mcpdm.c | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/omap-mcpdm.txt b/Documentation/devicetree/bindings/sound/omap-mcpdm.txt index 0741dff048dd..6f6c2f8e908d 100644 --- a/Documentation/devicetree/bindings/sound/omap-mcpdm.txt +++ b/Documentation/devicetree/bindings/sound/omap-mcpdm.txt @@ -8,6 +8,8 @@ Required properties: - interrupts: Interrupt number for McPDM - interrupt-parent: The parent interrupt controller - ti,hwmods: Name of the hwmod associated to the McPDM +- clocks: phandle for the pdmclk provider, likely <&twl6040> +- clock-names: Must be "pdmclk" Example: @@ -19,3 +21,11 @@ mcpdm: mcpdm@40132000 { interrupt-parent = <&gic>; ti,hwmods = "mcpdm"; }; + +In board DTS file the pdmclk needs to be added: + +&mcpdm { + clocks = <&twl6040>; + clock-names = "pdmclk"; + status = "okay"; +}; diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 74d6e6fdcfd0..e7cdc51fd806 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ struct omap_mcpdm { unsigned long phys_base; void __iomem *io_base; int irq; + struct clk *pdmclk; struct mutex mutex; @@ -388,6 +390,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); int ret; + clk_prepare_enable(mcpdm->pdmclk); pm_runtime_enable(mcpdm->dev); /* Disable lines while request is ongoing */ @@ -422,6 +425,7 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) pm_runtime_disable(mcpdm->dev); + clk_disable_unprepare(mcpdm->pdmclk); return 0; } @@ -441,6 +445,8 @@ static int omap_mcpdm_suspend(struct snd_soc_dai *dai) mcpdm->pm_active_count++; } + clk_disable_unprepare(mcpdm->pdmclk); + return 0; } @@ -448,6 +454,8 @@ static int omap_mcpdm_resume(struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + clk_prepare_enable(mcpdm->pdmclk); + if (mcpdm->pm_active_count) { while (mcpdm->pm_active_count--) pm_runtime_get_sync(mcpdm->dev); @@ -541,6 +549,15 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dev = &pdev->dev; + mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk"); + if (IS_ERR(mcpdm->pdmclk)) { + if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n", + PTR_ERR(mcpdm->pdmclk)); + mcpdm->pdmclk = NULL; + } + ret = devm_snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, &omap_mcpdm_dai, 1); -- cgit v1.3-14-g43fede From 170abcaae8bec0a53f2f7708a83119ec42fb09e2 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Mon, 11 Apr 2016 17:26:03 +0800 Subject: ASoC: rockchip: i2s: configure the sdio pins' iomux mode There are 3 i2s sdio pins, which iomux mode is as follows: - sdi3_sdo1 - sdi2_sdo2 - sdi1_sdo3 we need to configure these pins' iomux mode via the GRF register when use multi channel playback/capture. Signed-off-by: Sugar Zhang Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/rockchip-i2s.txt | 5 ++ sound/soc/rockchip/rockchip_i2s.c | 67 +++++++++++++++++++--- sound/soc/rockchip/rockchip_i2s.h | 7 +++ 3 files changed, 70 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt index 6e86d8aa29b4..4ea29aa9af59 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt @@ -23,6 +23,11 @@ Required properties: - rockchip,playback-channels: max playback channels, if not set, 8 channels default. - rockchip,capture-channels: max capture channels, if not set, 2 channels default. +Required properties for controller which support multi channels +playback/capture: + +- rockchip,grf: the phandle of the syscon node for GRF register. + Example for rk3288 I2S controller: i2s@ff890000 { diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 574c6af28c06..2f290f3a0ac7 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -11,8 +11,10 @@ */ #include +#include #include #include +#include #include #include #include @@ -23,6 +25,11 @@ #define DRV_NAME "rockchip-i2s" +struct rk_i2s_pins { + u32 reg_offset; + u32 shift; +}; + struct rk_i2s_dev { struct device *dev; @@ -33,6 +40,7 @@ struct rk_i2s_dev { struct snd_dmaengine_dai_dma_data playback_dma_data; struct regmap *regmap; + struct regmap *grf; /* * Used to indicate the tx/rx status. @@ -42,6 +50,7 @@ struct rk_i2s_dev { bool tx_start; bool rx_start; bool is_master_mode; + const struct rk_i2s_pins *pins; }; static int i2s_runtime_suspend(struct device *dev) @@ -300,6 +309,30 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, val); + if (!IS_ERR(i2s->grf) && i2s->pins) { + regmap_read(i2s->regmap, I2S_TXCR, &val); + val &= I2S_TXCR_CSR_MASK; + + switch (val) { + case I2S_CHN_4: + val = I2S_IO_4CH_OUT_6CH_IN; + break; + case I2S_CHN_6: + val = I2S_IO_6CH_OUT_4CH_IN; + break; + case I2S_CHN_8: + val = I2S_IO_8CH_OUT_2CH_IN; + break; + default: + val = I2S_IO_2CH_OUT_8CH_IN; + break; + } + + val <<= i2s->pins->shift; + val |= (I2S_IO_DIRECTION_MASK << i2s->pins->shift) << 16; + regmap_write(i2s->grf, i2s->pins->reg_offset, val); + } + regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, I2S_DMACR_TDL(16)); regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, @@ -485,9 +518,23 @@ static const struct regmap_config rockchip_i2s_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct rk_i2s_pins rk3399_i2s_pins = { + .reg_offset = 0xe220, + .shift = 11, +}; + +static const struct of_device_id rockchip_i2s_match[] = { + { .compatible = "rockchip,rk3066-i2s", }, + { .compatible = "rockchip,rk3188-i2s", }, + { .compatible = "rockchip,rk3288-i2s", }, + { .compatible = "rockchip,rk3399-i2s", .data = &rk3399_i2s_pins }, + {}, +}; + static int rockchip_i2s_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; + const struct of_device_id *of_id; struct rk_i2s_dev *i2s; struct snd_soc_dai_driver *soc_dai; struct resource *res; @@ -501,6 +548,17 @@ static int rockchip_i2s_probe(struct platform_device *pdev) return -ENOMEM; } + i2s->dev = &pdev->dev; + + i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); + if (!IS_ERR(i2s->grf)) { + of_id = of_match_device(rockchip_i2s_match, &pdev->dev); + if (!of_id || !of_id->data) + return -EINVAL; + + i2s->pins = of_id->data; + } + /* try to prepare related clocks */ i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk"); if (IS_ERR(i2s->hclk)) { @@ -540,7 +598,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev) i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->capture_dma_data.maxburst = 4; - i2s->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, i2s); pm_runtime_enable(&pdev->dev); @@ -606,14 +663,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id rockchip_i2s_match[] = { - { .compatible = "rockchip,rk3066-i2s", }, - { .compatible = "rockchip,rk3188-i2s", }, - { .compatible = "rockchip,rk3288-i2s", }, - { .compatible = "rockchip,rk3399-i2s", }, - {}, -}; - static const struct dev_pm_ops rockchip_i2s_pm_ops = { SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, NULL) diff --git a/sound/soc/rockchip/rockchip_i2s.h b/sound/soc/rockchip/rockchip_i2s.h index dc6e2c74d088..8e239d301bc7 100644 --- a/sound/soc/rockchip/rockchip_i2s.h +++ b/sound/soc/rockchip/rockchip_i2s.h @@ -236,4 +236,11 @@ enum { #define I2S_TXDR (0x0024) #define I2S_RXDR (0x0028) +/* io direction cfg register */ +#define I2S_IO_DIRECTION_MASK (7) +#define I2S_IO_8CH_OUT_2CH_IN (0) +#define I2S_IO_6CH_OUT_4CH_IN (4) +#define I2S_IO_4CH_OUT_6CH_IN (6) +#define I2S_IO_2CH_OUT_8CH_IN (7) + #endif /* _ROCKCHIP_IIS_H */ -- cgit v1.3-14-g43fede From ee12a817bb4b77ae06513959987c26b52c2ccae4 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 8 Apr 2016 18:54:57 +0200 Subject: ASoC: samsung: Remove unused Odroid x2/u3 machine driver We have been using "simple-audio-card" for Odroid X2/U3 boards, as can be seen from sound node in arch/arm/boot/dts/ exynos4412-odroid-common.dtsi. A dedicated machine driver is not needed and it is removed in this patch. There is no dts files using "samsung,odroidx2-audio" or "samsung,odroidu3-audio" compatible strings. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- .../bindings/sound/samsung,odroidx2-max98090.txt | 35 ---- sound/soc/samsung/Kconfig | 8 - sound/soc/samsung/Makefile | 2 - sound/soc/samsung/odroidx2_max98090.c | 185 --------------------- 4 files changed, 230 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/samsung,odroidx2-max98090.txt delete mode 100644 sound/soc/samsung/odroidx2_max98090.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/samsung,odroidx2-max98090.txt b/Documentation/devicetree/bindings/sound/samsung,odroidx2-max98090.txt deleted file mode 100644 index 9148f72319e1..000000000000 --- a/Documentation/devicetree/bindings/sound/samsung,odroidx2-max98090.txt +++ /dev/null @@ -1,35 +0,0 @@ -Samsung Exynos Odroid X2/U3 audio complex with MAX98090 codec - -Required properties: - - compatible : "samsung,odroidx2-audio" - for Odroid X2 board, - "samsung,odroidu3-audio" - for Odroid U3 board - - samsung,model : the user-visible name of this sound complex - - samsung,i2s-controller : the phandle of the I2S controller - - samsung,audio-codec : the phandle of the MAX98090 audio codec - - samsung,audio-routing : a list of the connections between audio - components; each entry is a pair of strings, the first being the - connection's sink, the second being the connection's source; - valid names for sources and sinks are the MAX98090's pins (as - documented in its binding), and the jacks on the board - For Odroid X2: - * Headphone Jack - * Mic Jack - * DMIC - - For Odroid U3: - * Headphone Jack - * Speakers - -Example: - -sound { - compatible = "samsung,odroidu3-audio"; - samsung,i2s-controller = <&i2s0>; - samsung,audio-codec = <&max98090>; - samsung,model = "Odroid-X2"; - samsung,audio-routing = - "Headphone Jack", "HPL", - "Headphone Jack", "HPR", - "IN1", "Mic Jack", - "Mic Jack", "MICBIAS"; -}; diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 78baa26e938b..7b722b0094d9 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -224,14 +224,6 @@ config SND_SOC_SNOW Say Y if you want to add audio support for various Snow boards based on Exynos5 series of SoCs. -config SND_SOC_ODROIDX2 - tristate "Audio support for Odroid-X2 and Odroid-U3" - depends on SND_SOC_SAMSUNG && I2C - select SND_SOC_MAX98090 - select SND_SAMSUNG_I2S - help - Say Y here to enable audio support for the Odroid-X2/U3. - config SND_SOC_ARNDALE_RT5631_ALC5631 tristate "Audio support for RT5631(ALC5631) on Arndale Board" depends on SND_SOC_SAMSUNG && I2C diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 052fe71be518..5d03f5ce6916 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -43,7 +43,6 @@ snd-soc-tobermory-objs := tobermory.o snd-soc-lowland-objs := lowland.o snd-soc-littlemill-objs := littlemill.o snd-soc-bells-objs := bells.o -snd-soc-odroidx2-max98090-objs := odroidx2_max98090.o snd-soc-arndale-rt5631-objs := arndale_rt5631.o obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o @@ -69,5 +68,4 @@ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o -obj-$(CONFIG_SND_SOC_ODROIDX2) += snd-soc-odroidx2-max98090.o obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c deleted file mode 100644 index 04217279fe25..000000000000 --- a/sound/soc/samsung/odroidx2_max98090.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2014 Samsung Electronics Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include "i2s.h" - -struct odroidx2_drv_data { - const struct snd_soc_dapm_widget *dapm_widgets; - unsigned int num_dapm_widgets; -}; - -/* The I2S CDCLK output clock frequency for the MAX98090 codec */ -#define MAX98090_MCLK 19200000 - -static struct snd_soc_dai_link odroidx2_dai[]; - -static int odroidx2_late_probe(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_dai *codec_dai; - struct snd_soc_dai *cpu_dai; - int ret; - - rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); - codec_dai = rtd->codec_dai; - cpu_dai = rtd->cpu_dai; - - ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, - SND_SOC_CLOCK_IN); - - if (ret < 0 || of_find_property(odroidx2_dai[0].codec_of_node, - "clocks", NULL)) - return ret; - - /* Set the cpu DAI configuration in order to use CDCLK */ - return snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_OUT); -} - -static const struct snd_soc_dapm_widget odroidx2_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_MIC("DMIC", NULL), -}; - -static const struct snd_soc_dapm_widget odroidu3_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speakers", NULL), -}; - -static struct snd_soc_dai_link odroidx2_dai[] = { - { - .name = "MAX98090", - .stream_name = "MAX98090 PCM", - .codec_dai_name = "HiFi", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, - } -}; - -static struct snd_soc_card odroidx2 = { - .owner = THIS_MODULE, - .dai_link = odroidx2_dai, - .num_links = ARRAY_SIZE(odroidx2_dai), - .fully_routed = true, - .late_probe = odroidx2_late_probe, -}; - -static const struct odroidx2_drv_data odroidx2_drvdata = { - .dapm_widgets = odroidx2_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(odroidx2_dapm_widgets), -}; - -static const struct odroidx2_drv_data odroidu3_drvdata = { - .dapm_widgets = odroidu3_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(odroidu3_dapm_widgets), -}; - -static const struct of_device_id odroidx2_audio_of_match[] = { - { - .compatible = "samsung,odroidx2-audio", - .data = &odroidx2_drvdata, - }, { - .compatible = "samsung,odroidu3-audio", - .data = &odroidu3_drvdata, - }, - { }, -}; -MODULE_DEVICE_TABLE(of, odroidx2_audio_of_match); - -static int odroidx2_audio_probe(struct platform_device *pdev) -{ - struct device_node *snd_node = pdev->dev.of_node; - struct snd_soc_card *card = &odroidx2; - struct device_node *i2s_node, *codec_node; - struct odroidx2_drv_data *dd; - const struct of_device_id *of_id; - int ret; - - of_id = of_match_node(odroidx2_audio_of_match, snd_node); - dd = (struct odroidx2_drv_data *)of_id->data; - - card->num_dapm_widgets = dd->num_dapm_widgets; - card->dapm_widgets = dd->dapm_widgets; - - card->dev = &pdev->dev; - - ret = snd_soc_of_parse_card_name(card, "samsung,model"); - if (ret < 0) - return ret; - - ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing"); - if (ret < 0) - return ret; - - codec_node = of_parse_phandle(snd_node, "samsung,audio-codec", 0); - if (!codec_node) { - dev_err(&pdev->dev, - "Failed parsing samsung,i2s-codec property\n"); - return -EINVAL; - } - - i2s_node = of_parse_phandle(snd_node, "samsung,i2s-controller", 0); - if (!i2s_node) { - dev_err(&pdev->dev, - "Failed parsing samsung,i2s-controller property\n"); - ret = -EINVAL; - goto err_put_codec_n; - } - - odroidx2_dai[0].codec_of_node = codec_node; - odroidx2_dai[0].cpu_of_node = i2s_node; - odroidx2_dai[0].platform_of_node = i2s_node; - - ret = snd_soc_register_card(card); - if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - goto err_put_i2s_n; - } - return 0; - -err_put_i2s_n: - of_node_put(i2s_node); -err_put_codec_n: - of_node_put(codec_node); - return ret; -} - -static int odroidx2_audio_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - - snd_soc_unregister_card(card); - - of_node_put(odroidx2_dai[0].cpu_of_node); - of_node_put(odroidx2_dai[0].codec_of_node); - - return 0; -} - -static struct platform_driver odroidx2_audio_driver = { - .driver = { - .name = "odroidx2-audio", - .of_match_table = odroidx2_audio_of_match, - .pm = &snd_soc_pm_ops, - }, - .probe = odroidx2_audio_probe, - .remove = odroidx2_audio_remove, -}; -module_platform_driver(odroidx2_audio_driver); - -MODULE_AUTHOR("Chen Zhen "); -MODULE_AUTHOR("Sylwester Nawrocki "); -MODULE_DESCRIPTION("ALSA SoC Odroid X2/U3 Audio Support"); -MODULE_LICENSE("GPL v2"); -- cgit v1.3-14-g43fede From b3c195b3a75b0aff9ede850ba2208cd1f40a702b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 19 May 2016 09:07:05 +0200 Subject: spi: orion: Add direct access mode This patch adds support for the direct access mode to the Orion SPI driver which is used on the Marvell Armada based SoCs. In this direct mode, all data written to (or read from) a specifically mapped MBus window (linked to one SPI chip-select on one of the SPI controllers) will be transferred directly to the SPI bus. Without the need to control the SPI registers in between. This can improve the SPI transfer rate in such cases. Both, direct-read and -write mode are supported. But only the write mode has been tested. This mode especially benefits from the SPI direct mode, as the data bytes are written head-to-head to the SPI bus, without any additional addresses. One use-case for this direct write mode is, programming a FPGA bitstream image into the FPGA connected to the SPI bus at maximum speed. This mode is described in chapter "22.5.2 Direct Write to SPI" in the Marvell Armada XP Functional Spec Datasheet. Signed-off-by: Stefan Roese Acked-by: Arnd Bergmann Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-orion.txt | 49 +++++++++++- drivers/spi/spi-orion.c | 88 ++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index 98bc69815eb3..4f629cc7634a 100644 --- a/Documentation/devicetree/bindings/spi/spi-orion.txt +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt @@ -8,7 +8,15 @@ Required properties: - "marvell,armada-380-spi", for the Armada 38x SoCs - "marvell,armada-390-spi", for the Armada 39x SoCs - "marvell,armada-xp-spi", for the Armada XP SoCs -- reg : offset and length of the register set for the device +- reg : offset and length of the register set for the device. + This property can optionally have additional entries to configure + the SPI direct access mode that some of the Marvell SoCs support + additionally to the normal indirect access (PIO) mode. The values + for the MBus "target" and "attribute" are defined in the Marvell + SoC "Functional Specifications" Manual in the chapter "Marvell + Core Processor Address Decoding". + The eight register sets following the control registers refer to + chip-select lines 0 through 7 respectively. - cell-index : Which of multiple SPI controllers is this. Optional properties: - interrupts : Is currently not used. @@ -23,3 +31,42 @@ Example: interrupts = <23>; status = "disabled"; }; + +Example with SPI direct mode support (optionally): + spi0: spi@10600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + reg = , /* control */ + , /* CS0 */ + , /* CS1 */ + , /* CS2 */ + , /* CS3 */ + , /* CS4 */ + , /* CS5 */ + , /* CS6 */ + ; /* CS7 */ + interrupts = <23>; + status = "disabled"; + }; + +To enable the direct mode, the board specific 'ranges' property in the +'soc' node needs to add the entries for the desired SPI controllers +and its chip-selects that are used in the direct mode instead of PIO +mode. Here an example for this (SPI controller 0, device 1 and SPI +controller 1, device 2 are used in direct mode. All other SPI device +are used in the default indirect (PIO) mode): + soc { + /* + * Enable the SPI direct access by configuring an entry + * here in the board-specific ranges property + */ + ranges = , /* internal regs */ + , /* BootROM */ + , /* SPI0-DEV1 */ + ; /* SPI1-DEV2 */ + +For further information on the MBus bindings, please see the MBus +DT documentation: +Documentation/devicetree/bindings/bus/mvebu-mbus.txt diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index a87cfd4ba17b..d0d9c8682b32 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ #define ORION_SPI_INT_CAUSE_REG 0x10 #define ORION_SPI_TIMING_PARAMS_REG 0x18 +/* Register for the "Direct Mode" */ +#define SPI_DIRECT_WRITE_CONFIG_REG 0x20 + #define ORION_SPI_TMISO_SAMPLE_MASK (0x3 << 6) #define ORION_SPI_TMISO_SAMPLE_1 (1 << 6) #define ORION_SPI_TMISO_SAMPLE_2 (2 << 6) @@ -78,11 +82,18 @@ struct orion_spi_dev { bool is_errata_50mhz_ac; }; +struct orion_direct_acc { + void __iomem *vaddr; + u32 size; +}; + struct orion_spi { struct spi_master *master; void __iomem *base; struct clk *clk; const struct orion_spi_dev *devdata; + + struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS]; }; static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) @@ -372,10 +383,39 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) { unsigned int count; int word_len; + struct orion_spi *orion_spi; + int cs = spi->chip_select; word_len = spi->bits_per_word; count = xfer->len; + orion_spi = spi_master_get_devdata(spi->master); + + /* + * Use SPI direct write mode if base address is available. Otherwise + * fall back to PIO mode for this transfer. + */ + if ((orion_spi->direct_access[cs].vaddr) && (xfer->tx_buf) && + (word_len == 8)) { + unsigned int cnt = count / 4; + unsigned int rem = count % 4; + + /* + * Send the TX-data to the SPI device via the direct + * mapped address window + */ + iowrite32_rep(orion_spi->direct_access[cs].vaddr, + xfer->tx_buf, cnt); + if (rem) { + u32 *buf = (u32 *)xfer->tx_buf; + + iowrite8_rep(orion_spi->direct_access[cs].vaddr, + &buf[cnt], rem); + } + + return count; + } + if (word_len == 8) { const u8 *tx = xfer->tx_buf; u8 *rx = xfer->rx_buf; @@ -425,6 +465,10 @@ static int orion_spi_reset(struct orion_spi *orion_spi) { /* Verify that the CS is deasserted */ orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); + + /* Don't deassert CS between the direct mapped SPI transfers */ + writel(0, spi_reg(orion_spi, SPI_DIRECT_WRITE_CONFIG_REG)); + return 0; } @@ -504,6 +548,7 @@ static int orion_spi_probe(struct platform_device *pdev) struct resource *r; unsigned long tclk_hz; int status = 0; + struct device_node *np; master = spi_alloc_master(&pdev->dev, sizeof(*spi)); if (master == NULL) { @@ -576,6 +621,49 @@ static int orion_spi_probe(struct platform_device *pdev) goto out_rel_clk; } + /* Scan all SPI devices of this controller for direct mapped devices */ + for_each_available_child_of_node(pdev->dev.of_node, np) { + u32 cs; + + /* Get chip-select number from the "reg" property */ + status = of_property_read_u32(np, "reg", &cs); + if (status) { + dev_err(&pdev->dev, + "%s has no valid 'reg' property (%d)\n", + np->full_name, status); + status = 0; + continue; + } + + /* + * Check if an address is configured for this SPI device. If + * not, the MBus mapping via the 'ranges' property in the 'soc' + * node is not configured and this device should not use the + * direct mode. In this case, just continue with the next + * device. + */ + status = of_address_to_resource(pdev->dev.of_node, cs + 1, r); + if (status) + continue; + + /* + * Only map one page for direct access. This is enough for the + * simple TX transfer which only writes to the first word. + * This needs to get extended for the direct SPI-NOR / SPI-NAND + * support, once this gets implemented. + */ + spi->direct_access[cs].vaddr = devm_ioremap(&pdev->dev, + r->start, + PAGE_SIZE); + if (IS_ERR(spi->direct_access[cs].vaddr)) { + status = PTR_ERR(spi->direct_access[cs].vaddr); + goto out_rel_clk; + } + spi->direct_access[cs].size = PAGE_SIZE; + + dev_info(&pdev->dev, "CS%d configured for direct access\n", cs); + } + pm_runtime_set_active(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); -- cgit v1.3-14-g43fede From b142f54ebf3809b9133673928d398641d692ddf0 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 13:36:43 +0200 Subject: crypto: doc - Fix typo Signed-off-by: Andrea Gelmini Signed-off-by: Herbert Xu --- Documentation/crypto/asymmetric-keys.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt index 8c07e0ea6bc0..2b7816dea370 100644 --- a/Documentation/crypto/asymmetric-keys.txt +++ b/Documentation/crypto/asymmetric-keys.txt @@ -76,7 +76,7 @@ the criterion string: Looking in /proc/keys, the last 8 hex digits of the key fingerprint are displayed, along with the subtype: - 1a39e171 I----- 1 perm 3f010000 0 0 asymmetri modsign.0: DSA 5acc2142 [] + 1a39e171 I----- 1 perm 3f010000 0 0 asymmetric modsign.0: DSA 5acc2142 [] ========================= -- cgit v1.3-14-g43fede From f8e4f9a0a85d3589d20c4c9f20e576cc8d3c99b6 Mon Sep 17 00:00:00 2001 From: Yendapally Reddy Dhananjaya Reddy Date: Fri, 27 May 2016 06:10:38 -0400 Subject: dt-bindings: rng: Northstar Plus SoC rng bindings Document the bindings used by Northstar Plus(NSP) SoC random number generator. Signed-off-by: Yendapally Reddy Dhananjaya Reddy Acked-by: Eric Anholt Signed-off-by: Herbert Xu --- Documentation/devicetree/bindings/rng/brcm,bcm2835.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt index 07ccdaa68324..aa304d412058 100644 --- a/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt +++ b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt @@ -2,7 +2,7 @@ BCM2835 Random number generator Required properties: -- compatible : should be "brcm,bcm2835-rng" +- compatible : should be "brcm,bcm2835-rng" or "brcm,bcm-nsp-rng" - reg : Specifies base physical address and size of the registers. Example: @@ -11,3 +11,8 @@ rng { compatible = "brcm,bcm2835-rng"; reg = <0x7e104000 0x10>; }; + +rng@18033000 { + compatible = "brcm,bcm-nsp-rng"; + reg = <0x18033000 0x14>; +}; -- cgit v1.3-14-g43fede From 8149afe4dbf91bead5632ac66f54f38b5d8b2391 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 3 May 2016 11:48:18 +0200 Subject: ARM: dts: exynos: Add initial support for Odroid XU board The Hardkernel's Odroid XU board was first design with big.LITTLE SoC from Samsung: the Exynos5410. Details: 1. Exynos5410 octa-core (A15+A7, however as of now only one cluster is enabled), 2. 2 GB DDR3 RAM, 3. PowerVR SGX544MP3 GPU (not enabled in DTS), 4. USB 3.0 Host x 1, USB 3.0 OTG x 1, USB 2.0 Host x 4, 5. HDMI 1.4a, MIPI DSI and Display Port (Display Port not on all of revisions though), 6. eMMC 4.5 and microSD slots. Comparing this board to Odroid XU3 (more popular), the differences are: 1. Exynos5410 instead of 5422, 2. MIPI DSI LCD connector, 3. Main PMIC: Maxim 77802 instead of S2MPS11, 4. USB3503+LAN9730 instead of integrated LAN9514, 5. eMMC 4.5 instead of eMMC 5.0, This patch adds initial support for the XU board with working basic functions, eMMC/SD and USB (including attached ethernet adapter). Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Reviewed-by: Javier Martinez Canillas Link: http://www.hardkernel.com/main/products/prdt_info.php?g_code=G137510300620 --- .../bindings/arm/samsung/samsung-boards.txt | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/exynos5410-odroidxu.dts | 121 +++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 arch/arm/boot/dts/exynos5410-odroidxu.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt index f5deace2b380..0ea7f14ef294 100644 --- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt +++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt @@ -47,6 +47,7 @@ Required root node properties: - "hardkernel,odroid-u3" - for Exynos4412-based Hardkernel Odroid U3. - "hardkernel,odroid-x" - for Exynos4412-based Hardkernel Odroid X. - "hardkernel,odroid-x2" - for Exynos4412-based Hardkernel Odroid X2. + - "hardkernel,odroid-xu" - for Exynos5410-based Hardkernel Odroid XU. - "hardkernel,odroid-xu3" - for Exynos5422-based Hardkernel Odroid XU3. - "hardkernel,odroid-xu3-lite" - for Exynos5422-based Hardkernel Odroid XU3 Lite board. diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 06b6c2d695bf..9a1fc0d39180 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -134,6 +134,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \ exynos5250-snow-rev5.dtb \ exynos5250-spring.dtb \ exynos5260-xyref5260.dtb \ + exynos5410-odroidxu.dtb \ exynos5410-smdk5410.dtb \ exynos5420-arndale-octa.dtb \ exynos5420-peach-pit.dtb \ diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts new file mode 100644 index 000000000000..9fe04500ecaf --- /dev/null +++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts @@ -0,0 +1,121 @@ +/* + * Hardkernel Odroid XU board device tree source + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Copyright (c) 2016 Krzysztof Kozlowski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/dts-v1/; +#include "exynos5410.dtsi" +#include +#include +#include "exynos54xx-odroidxu-leds.dtsi" + +/ { + model = "Hardkernel Odroid XU"; + compatible = "hardkernel,odroid-xu", "samsung,exynos5410", "samsung,exynos5"; + + memory { + reg = <0x40000000 0x7ea00000>; + }; + + chosen { + linux,stdout-path = &serial_2; + }; + + emmc_pwrseq: pwrseq { + pinctrl-0 = <&emmc_nrst_pin>; + pinctrl-names = "default"; + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpd1 0 GPIO_ACTIVE_LOW>; + }; + + fan0: pwm-fan { + compatible = "pwm-fan"; + pwms = <&pwm 0 20972 0>; + cooling-min-state = <0>; + cooling-max-state = <3>; + #cooling-cells = <2>; + cooling-levels = <0 130 170 230>; + }; + + fin_pll: xxti { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; + + firmware@02073000 { + compatible = "samsung,secure-firmware"; + reg = <0x02073000 0x1000>; + }; +}; + +&mmc_0 { + status = "okay"; + mmc-pwrseq = <&emmc_pwrseq>; + cd-gpios = <&gpc0 2 GPIO_ACTIVE_LOW>; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 4>; + samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + samsung,read-strobe-delay = <90>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8 &sd0_cd>; + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + mmc-hs400-1_8v; +}; + +&mmc_2 { + status = "okay"; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 4>; + samsung,dw-mshc-ddr-timing = <0 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>; + bus-width = <4>; + cap-sd-highspeed; +}; + +&pinctrl_0 { + emmc_nrst_pin: emmc-nrst { + samsung,pins = "gpd1-0"; + samsung,pin-function = <0>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; +}; + +&serial_0 { + status = "okay"; +}; + +&serial_1 { + status = "okay"; +}; + +&serial_2 { + status = "okay"; +}; + +&serial_3 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + dr_mode = "host"; +}; + +&usbdrd_dwc3_1 { + dr_mode = "peripheral"; +}; -- cgit v1.3-14-g43fede From bf1ecd210541ef5f3a110e88e8ca5d33b4aa5c23 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 31 May 2016 00:16:50 +0300 Subject: cfg80211: Allow cfg80211_connect_result() errors to be distinguished Previously, the status parameter to cfg80211_connect_result() was documented as using WLAN_STATUS_UNSPECIFIED_FAILURE (1) when the real status code for the failure is not known. This value can be used by an AP (and often is) and as such, user space cannot distinguish between explicitly rejected authentication/association and not being able to even try to associate or not receiving a response from the AP. Add a new inline function, cfg80211_connect_timeout(), to be used when the driver knows that the connection attempt failed due to a reason where connection could not be attempt or no response was received from the AP. The internal functions now allow a negative status value (-1) to be used as an indication of this special case. This results in the NL80211_ATTR_TIMED_OUT to be added to the NL80211_CMD_CONNECT event to allow user space to determine this case was hit. For backwards compatibility, NL80211_STATUS_CODE with the value WLAN_STATUS_UNSPECIFIED_FAILURE is still indicated in the event in such a case. Signed-off-by: Jouni Malinen [johannes: fix cfg80211_connect_bss() prototype to use int for status, add cfg80211_connect_timeout() to docbook, fix docbook] Signed-off-by: Johannes Berg --- Documentation/DocBook/80211.tmpl | 1 + include/net/cfg80211.h | 53 ++++++++++++++++++++++++++++++---------- include/uapi/linux/nl80211.h | 7 +++++- net/wireless/core.h | 4 +-- net/wireless/nl80211.c | 7 ++++-- net/wireless/nl80211.h | 2 +- net/wireless/sme.c | 8 +++--- 7 files changed, 58 insertions(+), 24 deletions(-) (limited to 'Documentation') diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 5f7c55999c77..800fe7a9024c 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -136,6 +136,7 @@ !Finclude/net/cfg80211.h cfg80211_ibss_joined !Finclude/net/cfg80211.h cfg80211_connect_result !Finclude/net/cfg80211.h cfg80211_connect_bss +!Finclude/net/cfg80211.h cfg80211_connect_timeout !Finclude/net/cfg80211.h cfg80211_roamed !Finclude/net/cfg80211.h cfg80211_disconnected !Finclude/net/cfg80211.h cfg80211_ready_on_channel diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 63921672bed0..537f010cf5e1 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2367,19 +2367,23 @@ struct cfg80211_qos_map { * (invoked with the wireless_dev mutex held) * * @connect: Connect to the ESS with the specified parameters. When connected, - * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. - * If the connection fails for some reason, call cfg80211_connect_result() - * with the status from the AP. The driver is allowed to roam to other - * BSSes within the ESS when the other BSS matches the connect parameters. - * When such roaming is initiated by the driver, the driver is expected to - * verify that the target matches the configured security parameters and - * to use Reassociation Request frame instead of Association Request frame. - * The connect function can also be used to request the driver to perform - * a specific roam when connected to an ESS. In that case, the prev_bssid + * call cfg80211_connect_result()/cfg80211_connect_bss() with status code + * %WLAN_STATUS_SUCCESS. If the connection fails for some reason, call + * cfg80211_connect_result()/cfg80211_connect_bss() with the status code + * from the AP or cfg80211_connect_timeout() if no frame with status code + * was received. + * The driver is allowed to roam to other BSSes within the ESS when the + * other BSS matches the connect parameters. When such roaming is initiated + * by the driver, the driver is expected to verify that the target matches + * the configured security parameters and to use Reassociation Request + * frame instead of Association Request frame. + * The connect function can also be used to request the driver to perform a + * specific roam when connected to an ESS. In that case, the prev_bssid * parameter is set to the BSSID of the currently associated BSS as an - * indication of requesting reassociation. In both the driver-initiated and - * new connect() call initiated roaming cases, the result of roaming is - * indicated with a call to cfg80211_roamed() or cfg80211_roamed_bss(). + * indication of requesting reassociation. + * In both the driver-initiated and new connect() call initiated roaming + * cases, the result of roaming is indicated with a call to + * cfg80211_roamed() or cfg80211_roamed_bss(). * (invoked with the wireless_dev mutex held) * @disconnect: Disconnect from the BSS/ESS. * (invoked with the wireless_dev mutex held) @@ -4680,7 +4684,7 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, struct cfg80211_bss *bss, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, - size_t resp_ie_len, u16 status, gfp_t gfp); + size_t resp_ie_len, int status, gfp_t gfp); /** * cfg80211_connect_result - notify cfg80211 of connection result @@ -4709,6 +4713,29 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid, resp_ie_len, status, gfp); } +/** + * cfg80211_connect_timeout - notify cfg80211 of connection timeout + * + * @dev: network device + * @bssid: the BSSID of the AP + * @req_ie: association request IEs (maybe be %NULL) + * @req_ie_len: association request IEs length + * @gfp: allocation flags + * + * It should be called by the underlying driver whenever connect() has failed + * in a sequence where no explicit authentication/association rejection was + * received from the AP. This could happen, e.g., due to not being able to send + * out the Authentication or Association Request frame or timing out while + * waiting for the response. + */ +static inline void +cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid, + const u8 *req_ie, size_t req_ie_len, gfp_t gfp) +{ + cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1, + gfp); +} + /** * cfg80211_roamed - notify cfg80211 of roaming * diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index e23d78685a01..8d995316aadb 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -493,7 +493,12 @@ * This attribute is ignored if driver does not support roam scan. * It is also sent as an event, with the BSSID and response IEs when the * connection is established or failed to be established. This can be - * determined by the STATUS_CODE attribute. + * determined by the %NL80211_ATTR_STATUS_CODE attribute (0 = success, + * non-zero = failure). If %NL80211_ATTR_TIMED_OUT is included in the + * event, the connection attempt failed due to not being able to initiate + * authentication/association or not receiving a response from the AP. + * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as + * well to remain backwards compatible. * @NL80211_CMD_ROAM: request that the card roam (currently not implemented), * sent as an event when the card/driver roamed by itself. * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify diff --git a/net/wireless/core.h b/net/wireless/core.h index 025b7a5d508b..a4d547f99f8d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -214,7 +214,7 @@ struct cfg80211_event { size_t req_ie_len; size_t resp_ie_len; struct cfg80211_bss *bss; - u16 status; + int status; /* -1 = failed; 0..65535 = status code */ } cr; struct { const u8 *req_ie; @@ -374,7 +374,7 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, - u16 status, bool wextev, + int status, bool wextev, struct cfg80211_bss *bss); void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, size_t ie_len, u16 reason, bool from_ap); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index bf75afa18699..03ac2ba8b174 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12092,7 +12092,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, - u16 status, gfp_t gfp) + int status, gfp_t gfp) { struct sk_buff *msg; void *hdr; @@ -12110,7 +12110,10 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) || - nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status) || + nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, + status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE : + status) || + (status < 0 && nla_put_flag(msg, NL80211_ATTR_TIMED_OUT)) || (req_ie && nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) || (resp_ie && diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 84d4edf1d545..a63f402b10b7 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -55,7 +55,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, - u16 status, gfp_t gfp); + int status, gfp_t gfp); void nl80211_send_roamed(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, const u8 *req_ie, size_t req_ie_len, diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 584fdc347221..add6824c44fd 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -244,9 +244,7 @@ void cfg80211_conn_work(struct work_struct *work) if (cfg80211_conn_do_work(wdev)) { __cfg80211_connect_result( wdev->netdev, bssid, - NULL, 0, NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - false, NULL); + NULL, 0, NULL, 0, -1, false, NULL); } wdev_unlock(wdev); } @@ -648,7 +646,7 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, - u16 status, bool wextev, + int status, bool wextev, struct cfg80211_bss *bss) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -757,7 +755,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, struct cfg80211_bss *bss, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, - size_t resp_ie_len, u16 status, gfp_t gfp) + size_t resp_ie_len, int status, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -- cgit v1.3-14-g43fede From 1eb1c5dc601a9f53d5bd53702d95afad337d35d2 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 20 May 2016 07:56:20 +0800 Subject: spi/rockchip: add rk3036/rk3228/rk3368 SoCs for spi document We had supported the rk3036/rk3066/rk3188/rk3228/rk3288/rk3368/rk3399 family SoCs in linux kernel. Let's add the other SoCs, in order to a better understanding from the rockchip spi document. Signed-off-by: Caesar Wang Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-rockchip.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt b/Documentation/devicetree/bindings/spi/spi-rockchip.txt index 1b14d69d8903..d2ca153614f9 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt @@ -6,10 +6,13 @@ and display controllers using the SPI communication interface. Required Properties: - compatible: should be one of the following. - "rockchip,rk3066-spi" for rk3066. - "rockchip,rk3188-spi", "rockchip,rk3066-spi" for rk3188. - "rockchip,rk3288-spi", "rockchip,rk3066-spi" for rk3288. - "rockchip,rk3399-spi", "rockchip,rk3066-spi" for rk3399. + "rockchip,rk3036-spi" for rk3036 SoCS. + "rockchip,rk3066-spi" for rk3066 SoCs. + "rockchip,rk3188-spi" for rk3188 SoCs. + "rockchip,rk3228-spi" for rk3228 SoCS. + "rockchip,rk3288-spi" for rk3288 SoCs. + "rockchip,rk3368-spi" for rk3368 SoCs. + "rockchip,rk3399-spi" for rk3399 SoCs. - reg: physical base address of the controller and length of memory mapped region. - interrupts: The interrupt number to the cpu. The interrupt specifier format -- cgit v1.3-14-g43fede From 36e5ecc2986f4712d8fdfc05ed1e5d39dda7096d Mon Sep 17 00:00:00 2001 From: Simran Rai Date: Tue, 17 May 2016 17:01:07 -0700 Subject: ASoC: cygnus: Add DT bindings for Broadcom Cygnus audio Add bindings for audio driver in Broadcom Cygnus. Signed-off-by: Lori Hikichi Signed-off-by: Simran Rai Reviewed-by: Ray Jui Reviewed-by: Scott Branden Acked-by: Rob Herring Signed-off-by: Mark Brown --- .../bindings/sound/brcm,cygnus-audio.txt | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt b/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt new file mode 100644 index 000000000000..b139e66d2a11 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt @@ -0,0 +1,67 @@ +BROADCOM Cygnus Audio I2S/TDM/SPDIF controller + +Required properties: + - compatible : "brcm,cygnus-audio" + - #address-cells: 32bit valued, 1 cell. + - #size-cells: 32bit valued, 0 cell. + - reg : Should contain audio registers location and length + - reg-names: names of the registers listed in "reg" property + Valid names are "aud" and "i2s_in". "aud" contains a + set of DMA, I2S_OUT and SPDIF registers. "i2s_in" contains + a set of I2S_IN registers. + - clocks: PLL and leaf clocks used by audio ports + - assigned-clocks: PLL and leaf clocks + - assigned-clock-parents: parent clocks of the assigned clocks + (usually the PLL) + - assigned-clock-rates: List of clock frequencies of the + assigned clocks + - clock-names: names of 3 leaf clocks used by audio ports + Valid names are "ch0_audio", "ch1_audio", "ch2_audio" + - interrupts: audio DMA interrupt number + +SSP Subnode properties: +- reg: The index of ssp port interface to use + Valid value are 0, 1, 2, or 3 (for spdif) + +Example: + cygnus_audio: audio@180ae000 { + compatible = "brcm,cygnus-audio"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x180ae000 0xafd>, <0x180aec00 0x1f8>; + reg-names = "aud", "i2s_in"; + clocks = <&audiopll BCM_CYGNUS_AUDIOPLL_CH0>, + <&audiopll BCM_CYGNUS_AUDIOPLL_CH1>, + <&audiopll BCM_CYGNUS_AUDIOPLL_CH2>; + assigned-clocks = <&audiopll BCM_CYGNUS_AUDIOPLL>, + <&audiopll BCM_CYGNUS_AUDIOPLL_CH0>, + <&audiopll BCM_CYGNUS_AUDIOPLL_CH1>, + <&audiopll BCM_CYGNUS_AUDIOPLL_CH2>; + assigned-clock-parents = <&audiopll BCM_CYGNUS_AUDIOPLL>; + assigned-clock-rates = <1769470191>, + <0>, + <0>, + <0>; + clock-names = "ch0_audio", "ch1_audio", "ch2_audio"; + interrupts = ; + + ssp0: ssp_port@0 { + reg = <0>; + status = "okay"; + }; + + ssp1: ssp_port@1 { + reg = <1>; + status = "disabled"; + }; + + ssp2: ssp_port@2 { + reg = <2>; + status = "disabled"; + }; + + spdif: spdif_port@3 { + reg = <3>; + status = "disabled"; + }; + }; -- cgit v1.3-14-g43fede From 500d336669ae9b2fb605a4ac0b478e2858e75a07 Mon Sep 17 00:00:00 2001 From: Chris Brand Date: Thu, 28 Apr 2016 10:59:57 -0700 Subject: Documentation: Binding docs for bcm11351 enable method Commit 84320e1a635fcf90cff4185f029ce9e31bf1d4a7 ("ARM: BCM: Clean up SMP support for Broadcom Kona") moved the "secondary-boot-reg" property from the "cpus" node to the individual "cpu" nodes but negelected to update brcm,bcm11351-cpu-method.txt to match. bcm11351-cpu-method was apparently never added to the list of methods in bindings/arm/cpus.txt. bindings/arm/cpus.txt states that "enable-method" should be a property of the "cpu" node rather than the "cpus" node. This patch rectifies these two omissions and one inconsistency. Signed-off-by: Chris Brand Acked-by: Rob Herring Signed-off-by: Florian Fainelli --- .../devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt | 6 +++--- Documentation/devicetree/bindings/arm/cpus.txt | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt index 8240c023e202..e3f996920403 100644 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt @@ -5,7 +5,7 @@ CPUs in the following Broadcom SoCs: BCM11130, BCM11140, BCM11351, BCM28145, BCM28155, BCM21664 The enable method is specified by defining the following required -properties in the "cpus" device tree node: +properties in the "cpu" device tree node: - enable-method = "brcm,bcm11351-cpu-method"; - secondary-boot-reg = <...>; @@ -19,8 +19,6 @@ Example: cpus { #address-cells = <1>; #size-cells = <0>; - enable-method = "brcm,bcm11351-cpu-method"; - secondary-boot-reg = <0x3500417c>; cpu0: cpu@0 { device_type = "cpu"; @@ -32,5 +30,7 @@ Example: device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <1>; + enable-method = "brcm,bcm11351-cpu-method"; + secondary-boot-reg = <0x3500417c>; }; }; diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 3f0cbbb8395f..e97a45681138 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -193,6 +193,7 @@ nodes to be present and contain the properties described below. "allwinner,sun6i-a31" "allwinner,sun8i-a23" "arm,realview-smp" + "brcm,bcm11351-cpu-method" "brcm,bcm-nsp-smp" "brcm,brahma-b15" "marvell,armada-375-smp" -- cgit v1.3-14-g43fede From 6e62688c1d0b568fa5451341bdd7f382c80ac338 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 28 Mar 2016 10:18:29 +0530 Subject: dt-bindings: ata: add compatible string for iProc AHCI controller The Broadcom iProc SoCs have AHCI compliant SATA controller. This patch adds common compatible string for AHCI SATA controller on iProc SoCs. Signed-off-by: Anup Patel Acked-by: Rob Herring Signed-off-by: Florian Fainelli --- Documentation/devicetree/bindings/ata/ahci-platform.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index 87adfb227ca9..fedc213b5f1a 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -10,6 +10,7 @@ PHYs. Required properties: - compatible : compatible string, one of: - "allwinner,sun4i-a10-ahci" + - "brcm,iproc-ahci" - "hisilicon,hisi-ahci" - "cavium,octeon-7130-ahci" - "ibm,476gtr-ahci" -- cgit v1.3-14-g43fede From 79795e20a184ebabf4ae743d1506cc39783caa46 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 30 May 2016 15:27:16 +0200 Subject: dt-bindings: reset: Add bindings for the Meson SoC Reset Controller Add DT bindings for the Meson SoC Reset Controller documentation and the associated include file. Acked-by: Rob Herring Signed-off-by: Neil Armstrong Signed-off-by: Philipp Zabel --- .../bindings/reset/amlogic,meson-reset.txt | 18 ++ .../dt-bindings/reset/amlogic,meson-gxbb-reset.h | 210 +++++++++++++++++++++ include/dt-bindings/reset/amlogic,meson8b-reset.h | 175 +++++++++++++++++ 3 files changed, 403 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt create mode 100644 include/dt-bindings/reset/amlogic,meson-gxbb-reset.h create mode 100644 include/dt-bindings/reset/amlogic,meson8b-reset.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt new file mode 100644 index 000000000000..e746b631793a --- /dev/null +++ b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.txt @@ -0,0 +1,18 @@ +Amlogic Meson SoC Reset Controller +======================================= + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "amlogic,meson8b-reset" or "amlogic,meson-gxbb-reset" +- reg: should contain the register address base +- #reset-cells: 1, see below + +example: + +reset: reset-controller { + compatible = "amlogic,meson-gxbb-reset"; + reg = <0x0 0x04404 0x0 0x20>; + #reset-cells = <1>; +}; diff --git a/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h b/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h new file mode 100644 index 000000000000..524d6077ac1b --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson-gxbb-reset.h @@ -0,0 +1,210 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * BSD LICENSE + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _DT_BINDINGS_AMLOGIC_MESON_GXBB_RESET_H +#define _DT_BINDINGS_AMLOGIC_MESON_GXBB_RESET_H + +/* RESET0 */ +#define RESET_HIU 0 +/* 1 */ +#define RESET_DOS_RESET 2 +#define RESET_DDR_TOP 3 +#define RESET_DCU_RESET 4 +#define RESET_VIU 5 +#define RESET_AIU 6 +#define RESET_VID_PLL_DIV 7 +/* 8 */ +#define RESET_PMUX 9 +#define RESET_VENC 10 +#define RESET_ASSIST 11 +#define RESET_AFIFO2 12 +#define RESET_VCBUS 13 +/* 14 */ +/* 15 */ +#define RESET_GIC 16 +#define RESET_CAPB3_DECODE 17 +#define RESET_NAND_CAPB3 18 +#define RESET_HDMITX_CAPB3 19 +#define RESET_MALI_CAPB3 20 +#define RESET_DOS_CAPB3 21 +#define RESET_SYS_CPU_CAPB3 22 +#define RESET_CBUS_CAPB3 23 +#define RESET_AHB_CNTL 24 +#define RESET_AHB_DATA 25 +#define RESET_VCBUS_CLK81 26 +#define RESET_MMC 27 +#define RESET_MIPI_0 28 +#define RESET_MIPI_1 29 +#define RESET_MIPI_2 30 +#define RESET_MIPI_3 31 +/* RESET1 */ +#define RESET_CPPM 32 +#define RESET_DEMUX 33 +#define RESET_USB_OTG 34 +#define RESET_DDR 35 +#define RESET_AO_RESET 36 +#define RESET_BT656 37 +#define RESET_AHB_SRAM 38 +/* 39 */ +#define RESET_PARSER 40 +#define RESET_BLKMV 41 +#define RESET_ISA 42 +#define RESET_ETHERNET 43 +#define RESET_SD_EMMC_A 44 +#define RESET_SD_EMMC_B 45 +#define RESET_SD_EMMC_C 46 +#define RESET_ROM_BOOT 47 +#define RESET_SYS_CPU_0 48 +#define RESET_SYS_CPU_1 49 +#define RESET_SYS_CPU_2 50 +#define RESET_SYS_CPU_3 51 +#define RESET_SYS_CPU_CORE_0 52 +#define RESET_SYS_CPU_CORE_1 53 +#define RESET_SYS_CPU_CORE_2 54 +#define RESET_SYS_CPU_CORE_3 55 +#define RESET_SYS_PLL_DIV 56 +#define RESET_SYS_CPU_AXI 57 +#define RESET_SYS_CPU_L2 58 +#define RESET_SYS_CPU_P 59 +#define RESET_SYS_CPU_MBIST 60 +/* 61 */ +/* 62 */ +/* 63 */ +/* RESET2 */ +#define RESET_VD_RMEM 64 +#define RESET_AUDIN 65 +#define RESET_HDMI_TX 66 +/* 67 */ +/* 68 */ +/* 69 */ +#define RESET_GE2D 70 +#define RESET_PARSER_REG 71 +#define RESET_PARSER_FETCH 72 +#define RESET_PARSER_CTL 73 +#define RESET_PARSER_TOP 74 +/* 75 */ +/* 76 */ +#define RESET_AO_CPU_RESET 77 +#define RESET_MALI 78 +#define RESET_HDMI_SYSTEM_RESET 79 +/* 80-95 */ +/* RESET3 */ +#define RESET_RING_OSCILLATOR 96 +#define RESET_SYS_CPU 97 +#define RESET_EFUSE 98 +#define RESET_SYS_CPU_BVCI 99 +#define RESET_AIFIFO 100 +#define RESET_TVFE 101 +#define RESET_AHB_BRIDGE_CNTL 102 +/* 103 */ +#define RESET_AUDIO_DAC 104 +#define RESET_DEMUX_TOP 105 +#define RESET_DEMUX_DES 106 +#define RESET_DEMUX_S2P_0 107 +#define RESET_DEMUX_S2P_1 108 +#define RESET_DEMUX_RESET_0 109 +#define RESET_DEMUX_RESET_1 110 +#define RESET_DEMUX_RESET_2 111 +/* 112-127 */ +/* RESET4 */ +/* 128 */ +/* 129 */ +/* 130 */ +/* 131 */ +#define RESET_DVIN_RESET 132 +#define RESET_RDMA 133 +#define RESET_VENCI 134 +#define RESET_VENCP 135 +/* 136 */ +#define RESET_VDAC 137 +#define RESET_RTC 138 +/* 139 */ +#define RESET_VDI6 140 +#define RESET_VENCL 141 +#define RESET_I2C_MASTER_2 142 +#define RESET_I2C_MASTER_1 143 +/* 144-159 */ +/* RESET5 */ +/* 160-191 */ +/* RESET6 */ +#define RESET_PERIPHS_GENERAL 192 +#define RESET_PERIPHS_SPICC 193 +#define RESET_PERIPHS_SMART_CARD 194 +#define RESET_PERIPHS_SAR_ADC 195 +#define RESET_PERIPHS_I2C_MASTER_0 196 +#define RESET_SANA 197 +/* 198 */ +#define RESET_PERIPHS_STREAM_INTERFACE 199 +#define RESET_PERIPHS_SDIO 200 +#define RESET_PERIPHS_UART_0 201 +#define RESET_PERIPHS_UART_1_2 202 +#define RESET_PERIPHS_ASYNC_0 203 +#define RESET_PERIPHS_ASYNC_1 204 +#define RESET_PERIPHS_SPI_0 205 +#define RESET_PERIPHS_SDHC 206 +#define RESET_UART_SLIP 207 +/* 208-223 */ +/* RESET7 */ +#define RESET_USB_DDR_0 224 +#define RESET_USB_DDR_1 225 +#define RESET_USB_DDR_2 226 +#define RESET_USB_DDR_3 227 +/* 228 */ +#define RESET_DEVICE_MMC_ARB 229 +/* 230 */ +#define RESET_VID_LOCK 231 +#define RESET_A9_DMC_PIPEL 232 +/* 233-255 */ + +#endif diff --git a/include/dt-bindings/reset/amlogic,meson8b-reset.h b/include/dt-bindings/reset/amlogic,meson8b-reset.h new file mode 100644 index 000000000000..614aff2c7aff --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson8b-reset.h @@ -0,0 +1,175 @@ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * BSD LICENSE + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _DT_BINDINGS_AMLOGIC_MESON8B_RESET_H +#define _DT_BINDINGS_AMLOGIC_MESON8B_RESET_H + +/* RESET0 */ +#define RESET_HIU 0 +#define RESET_VLD 1 +#define RESET_IQIDCT 2 +#define RESET_MC 3 +/* 8 */ +#define RESET_VIU 5 +#define RESET_AIU 6 +#define RESET_MCPU 7 +#define RESET_CCPU 8 +#define RESET_PMUX 9 +#define RESET_VENC 10 +#define RESET_ASSIST 11 +#define RESET_AFIFO2 12 +#define RESET_MDEC 13 +#define RESET_VLD_PART 14 +#define RESET_VIFIFO 15 +/* 16-31 */ +/* RESET1 */ +/* 32 */ +#define RESET_DEMUX 33 +#define RESET_USB_OTG 34 +#define RESET_DDR 35 +#define RESET_VDAC_1 36 +#define RESET_BT656 37 +#define RESET_AHB_SRAM 38 +#define RESET_AHB_BRIDGE 39 +#define RESET_PARSER 40 +#define RESET_BLKMV 41 +#define RESET_ISA 42 +#define RESET_ETHERNET 43 +#define RESET_ABUF 44 +#define RESET_AHB_DATA 45 +#define RESET_AHB_CNTL 46 +#define RESET_ROM_BOOT 47 +/* 48-63 */ +/* RESET2 */ +#define RESET_VD_RMEM 64 +#define RESET_AUDIN 65 +#define RESET_DBLK 66 +#define RESET_PIC_DC 66 +#define RESET_PSC 66 +#define RESET_NAND 66 +#define RESET_GE2D 70 +#define RESET_PARSER_REG 71 +#define RESET_PARSER_FETCH 72 +#define RESET_PARSER_CTL 73 +#define RESET_PARSER_TOP 74 +#define RESET_HDMI_APB 75 +#define RESET_AUDIO_APB 76 +#define RESET_MEDIA_CPU 77 +#define RESET_MALI 78 +#define RESET_HDMI_SYSTEM_RESET 79 +/* 80-95 */ +/* RESET3 */ +#define RESET_RING_OSCILLATOR 96 +#define RESET_SYS_CPU_0 97 +#define RESET_EFUSE 98 +#define RESET_SYS_CPU_BVCI 99 +#define RESET_AIFIFO 100 +#define RESET_AUDIO_PLL_MODULATOR 101 +#define RESET_AHB_BRIDGE_CNTL 102 +#define RESET_SYS_CPU_1 103 +#define RESET_AUDIO_DAC 104 +#define RESET_DEMUX_TOP 105 +#define RESET_DEMUX_DES 106 +#define RESET_DEMUX_S2P_0 107 +#define RESET_DEMUX_S2P_1 108 +#define RESET_DEMUX_RESET_0 109 +#define RESET_DEMUX_RESET_1 110 +#define RESET_DEMUX_RESET_2 111 +/* 112-127 */ +/* RESET4 */ +#define RESET_PL310 128 +#define RESET_A5_APB 129 +#define RESET_A5_AXI 130 +#define RESET_A5 131 +#define RESET_DVIN 132 +#define RESET_RDMA 133 +#define RESET_VENCI 134 +#define RESET_VENCP 135 +#define RESET_VENCT 136 +#define RESET_VDAC_4 137 +#define RESET_RTC 138 +#define RESET_A5_DEBUG 139 +#define RESET_VDI6 140 +#define RESET_VENCL 141 +/* 142-159 */ +/* RESET5 */ +#define RESET_DDR_PLL 160 +#define RESET_MISC_PLL 161 +#define RESET_SYS_PLL 162 +#define RESET_HPLL_PLL 163 +#define RESET_AUDIO_PLL 164 +#define RESET_VID2_PLL 165 +/* 166-191 */ +/* RESET6 */ +#define RESET_PERIPHS_GENERAL 192 +#define RESET_PERIPHS_IR_REMOTE 193 +#define RESET_PERIPHS_SMART_CARD 194 +#define RESET_PERIPHS_SAR_ADC 195 +#define RESET_PERIPHS_I2C_MASTER_0 196 +#define RESET_PERIPHS_I2C_MASTER_1 197 +#define RESET_PERIPHS_I2C_SLAVE 198 +#define RESET_PERIPHS_STREAM_INTERFACE 199 +#define RESET_PERIPHS_SDIO 200 +#define RESET_PERIPHS_UART_0 201 +#define RESET_PERIPHS_UART_1 202 +#define RESET_PERIPHS_ASYNC_0 203 +#define RESET_PERIPHS_ASYNC_1 204 +#define RESET_PERIPHS_SPI_0 205 +#define RESET_PERIPHS_SPI_1 206 +#define RESET_PERIPHS_LED_PWM 207 +/* 208-223 */ +/* RESET7 */ +/* 224-255 */ + +#endif -- cgit v1.3-14-g43fede From ba35018593547eac69998e2571fc95cf620f2220 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 31 May 2016 18:09:12 +0300 Subject: Documentation/sphinx: fix kernel-doc extension on python3 Reconcile differences between python2 and python3 on dealing with stdout, stderr from Popen. This fixes "name 'unicode' is not defined" errors on python3. We'll need to try to keep the extension working on both python-sphinx and python3-sphinx so we don't need two copies. Reported-and-tested-by: Marius Vlad Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 87a1332fe934..a6e170872c8a 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -23,6 +23,9 @@ # # Authors: # Jani Nikula +# +# Please make sure this works on both python2 and python3. +# import os import subprocess @@ -75,8 +78,10 @@ class KernelDocDirective(Directive): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out, err = p.communicate() - # assume the kernel sources are utf-8 - out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') + # python2 needs conversion to unicode. + # python3 with universal_newlines=True returns strings. + if sys.version_info.major < 3: + out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) -- cgit v1.3-14-g43fede From 9cc1a44c03113cb2f3be73650d7c611c3e273ada Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Jun 2016 11:12:42 +0200 Subject: doc/sphinx: Pass right filename as source With this error output becomes almost readable. The line numbers are still totally bonghits, but that's a lot harder to pull out of kerneldoc. We'd essentially have to insert some special markers in the kernel-doc output, split the output along these markers and then insert each block separately using state_machine.insert_input(block, source, first_line) Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index a6e170872c8a..9fc2c27916a9 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -57,7 +57,7 @@ class KernelDocDirective(Directive): env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) - source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) + source = filename # FIXME: make this nicer and more robust against errors if 'export' in self.options: -- cgit v1.3-14-g43fede From 551a626c9b1b2c2d983e75fb75c20935eff67abb Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Mon, 2 May 2016 10:02:16 +0200 Subject: documentation: Add compatibles for Amlogic Meson GXBB pin controllers Add the two new compatibles for the Amlogic Meson GXBB pin controllers. Signed-off-by: Carlo Caione Signed-off-by: Kevin Hilman --- Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt index 32f4a2d6d0b3..fe7fe0b03cfb 100644 --- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt @@ -5,6 +5,8 @@ Required properties for the root node: "amlogic,meson8b-cbus-pinctrl" "amlogic,meson8-aobus-pinctrl" "amlogic,meson8b-aobus-pinctrl" + "amlogic,meson-gxbb-periphs-pinctrl" + "amlogic,meson-gxbb-aobus-pinctrl" - reg: address and size of registers controlling irq functionality === GPIO sub-nodes === -- cgit v1.3-14-g43fede From 1fdab21d1d52a85c31f932844242fec5fb81daac Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 23 May 2016 09:44:55 +0200 Subject: memory: atmel-ebi: add DT bindings documentation The EBI (External Bus Interface) is used to access external peripherals (NOR, SRAM, NAND, and other specific devices like ethernet controllers). Each device is assigned a CS line and an address range and can have its own configuration (timings, access mode, bus width, ...). This driver provides a generic DT binding to configure a device according to its requirements. For specific device controllers (like the NAND one) the SMC timings should be configured by the controller driver through the matrix and smc syscon regmaps. Signed-off-by: Boris Brezillon Acked-by: Rob Herring Signed-off-by: Alexandre Belloni --- .../bindings/memory-controllers/atmel,ebi.txt | 136 +++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt b/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt new file mode 100644 index 000000000000..9bb5f57e2066 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt @@ -0,0 +1,136 @@ +* Device tree bindings for Atmel EBI + +The External Bus Interface (EBI) controller is a bus where you can connect +asynchronous (NAND, NOR, SRAM, ....) and synchronous memories (SDR/DDR SDRAMs). +The EBI provides a glue-less interface to asynchronous memories through the SMC +(Static Memory Controller). + +Required properties: + +- compatible: "atmel,at91sam9260-ebi" + "atmel,at91sam9261-ebi" + "atmel,at91sam9263-ebi0" + "atmel,at91sam9263-ebi1" + "atmel,at91sam9rl-ebi" + "atmel,at91sam9g45-ebi" + "atmel,at91sam9x5-ebi" + "atmel,sama5d3-ebi" + +- reg: Contains offset/length value for EBI memory mapping. + This property might contain several entries if the EBI + memory range is not contiguous + +- #address-cells: Must be 2. + The first cell encodes the CS. + The second cell encode the offset into the CS memory + range. + +- #size-cells: Must be set to 1. + +- ranges: Encodes CS to memory region association. + +- clocks: Clock feeding the EBI controller. + See clock-bindings.txt + +Children device nodes are representing device connected to the EBI bus. + +Required device node properties: + +- reg: Contains the chip-select id, the offset and the length + of the memory region requested by the device. + +EBI bus configuration will be defined directly in the device subnode. + +Optional EBI/SMC properties: + +- atmel,smc-bus-width: width of the asynchronous device's data bus + 8, 16 or 32. + Default to 8 when undefined. + +- atmel,smc-byte-access-type "write" or "select" (see Atmel datasheet). + Default to "select" when undefined. + +- atmel,smc-read-mode "nrd" or "ncs". + Default to "ncs" when undefined. + +- atmel,smc-write-mode "nwe" or "ncs". + Default to "ncs" when undefined. + +- atmel,smc-exnw-mode "disabled", "frozen" or "ready". + Default to "disabled" when undefined. + +- atmel,smc-page-mode enable page mode if present. The provided value + defines the page size (supported values: 4, 8, + 16 and 32). + +- atmel,smc-tdf-mode: "normal" or "optimized". When set to + "optimized" the data float time is optimized + depending on the next device being accessed + (next device setup time is subtracted to the + current device data float time). + Default to "normal" when undefined. + +If at least one atmel,smc- property is defined the following SMC timing +properties become mandatory. In the other hand, if none of the atmel,smc- +properties are specified, we assume that the EBI bus configuration will be +handled by the sub-device driver, and none of those properties should be +defined. + +All the timings are expressed in nanoseconds (see Atmel datasheet for a full +description). + +- atmel,smc-ncs-rd-setup-ns +- atmel,smc-nrd-setup-ns +- atmel,smc-ncs-wr-setup-ns +- atmel,smc-nwe-setup-ns +- atmel,smc-ncs-rd-pulse-ns +- atmel,smc-nrd-pulse-ns +- atmel,smc-ncs-wr-pulse-ns +- atmel,smc-nwe-pulse-ns +- atmel,smc-nwe-cycle-ns +- atmel,smc-nrd-cycle-ns +- atmel,smc-tdf-ns + +Example: + + ebi: ebi@10000000 { + compatible = "atmel,sama5d3-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&hsmc>; + atmel,matrix = <&matrix>; + reg = <0x10000000 0x10000000 + 0x40000000 0x30000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x40000000 0x10000000 + 0x2 0x0 0x50000000 0x10000000 + 0x3 0x0 0x60000000 0x10000000>; + clocks = <&mck>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ebi_addr>; + + nor: flash@0,0 { + compatible = "cfi-flash"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0 0x0 0x1000000>; + bank-width = <2>; + + atmel,smc-read-mode = "nrd"; + atmel,smc-write-mode = "nwe"; + atmel,smc-bus-width = <16>; + atmel,smc-ncs-rd-setup-ns = <0>; + atmel,smc-ncs-wr-setup-ns = <0>; + atmel,smc-nwe-setup-ns = <8>; + atmel,smc-nrd-setup-ns = <16>; + atmel,smc-ncs-rd-pulse-ns = <84>; + atmel,smc-ncs-wr-pulse-ns = <84>; + atmel,smc-nrd-pulse-ns = <76>; + atmel,smc-nwe-pulse-ns = <76>; + atmel,smc-nrd-cycle-ns = <107>; + atmel,smc-nwe-cycle-ns = <84>; + atmel,smc-tdf-ns = <16>; + }; + }; + -- cgit v1.3-14-g43fede From 10ff08029d9880e4bf70de0535f34ce239af7a9a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 31 May 2016 17:41:50 -0300 Subject: ASoC: sgtl5000: Place optional properties in the correct section 'micbias-resistor-k-ohms' and 'micbias-voltage-m-volts' are optional properties, so move them below the 'Optional properties' line. While at it, fix a typo in 'mentioned'. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/sgtl5000.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt index 0e5e4eb3ef1b..5666da7b8605 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -7,6 +7,14 @@ Required properties: - clocks : the clock provider of SYS_MCLK +- VDDA-supply : the regulator provider of VDDA + +- VDDIO-supply: the regulator provider of VDDIO + +Optional properties: + +- VDDD-supply : the regulator provider of VDDD + - micbias-resistor-k-ohms : the bias resistor to be used in kOmhs The resistor can take values of 2k, 4k or 8k. If set to 0 it will be off. @@ -15,17 +23,9 @@ Required properties: - micbias-voltage-m-volts : the bias voltage to be used in mVolts The voltage can take values from 1.25V to 3V by 250mV steps - If this node is not mentionned or the value is unknown, then + If this node is not mentioned or the value is unknown, then the value is set to 1.25V. -- VDDA-supply : the regulator provider of VDDA - -- VDDIO-supply: the regulator provider of VDDIO - -Optional properties: - -- VDDD-supply : the regulator provider of VDDD - Example: codec: sgtl5000@0a { -- cgit v1.3-14-g43fede From 254a13811ef41932b1315f524943050e6b5ae5a1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 2 Jun 2016 14:19:41 +0200 Subject: ASoC: Add ADAU7002 Stereo PDM-to-I2S/TDM Converter DT bindings The ADAU7002 takes a stereo PDM signal (e.g. from two digital microphones) and converts it into a I2S/TDM PCM stream. The chip does not have a control interface and has a single power supply that is modeled in the devicetree. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/adi,adau7002.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/adi,adau7002.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/adi,adau7002.txt b/Documentation/devicetree/bindings/sound/adi,adau7002.txt new file mode 100644 index 000000000000..f144ee1abf85 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,adau7002.txt @@ -0,0 +1,19 @@ +Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter + +Required properties: + + - compatible: Must be "adi,adau7002" + +Optional properties: + + - IOVDD-supply: Phandle and specifier for the power supply providing the IOVDD + supply as covered in Documentation/devicetree/bindings/regulator/regulator.txt + + If this property is not present it is assumed that the supply pin is + hardwired to always on. + +Example: + adau7002: pdm-to-i2s { + compatible = "adi,adau7002"; + IOVDD-supply = <&supply>; + }; -- cgit v1.3-14-g43fede From 0c198ed2ba68b6cc728c5aa3c5486d9e5c328ecd Mon Sep 17 00:00:00 2001 From: PC Liao Date: Wed, 1 Jun 2016 20:00:12 +0800 Subject: ASoC: mediatek: add MCLK source selection The new machine's MCLK source is from mt8173 which is dynamic from sampling rate*256. This patch provides the selection for device tree. Signed-off-by: PC Liao Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/mt8173-rt5650.txt | 5 +++ sound/soc/mediatek/mt8173-rt5650.c | 45 +++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt index 5bfa6b60530b..f250fc7c7acc 100644 --- a/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt @@ -12,12 +12,17 @@ Required codec-capture subnode properties: <&rt5650 0> : Default setting. Connect rt5650 I2S1 for capture. (dai_name = rt5645-aif1) <&rt5650 1> : Connect rt5650 I2S2 for capture. (dai_name = rt5645-aif2) +- mediatek,mclk: the MCLK source + 0 : external oscillator, MCLK = 12.288M + 1 : internal source from mt8173, MCLK = sampling rate*256 + Example: sound { compatible = "mediatek,mt8173-rt5650"; mediatek,audio-codec = <&rt5650>; mediatek,platform = <&afe>; + mediatek,mclk = <0>; codec-capture { sound-dai = <&rt5650 1>; }; diff --git a/sound/soc/mediatek/mt8173-rt5650.c b/sound/soc/mediatek/mt8173-rt5650.c index a27a6673dbe3..072934b470a8 100644 --- a/sound/soc/mediatek/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173-rt5650.c @@ -23,6 +23,20 @@ #define MCLK_FOR_CODECS 12288000 +enum mt8173_rt5650_mclk { + MT8173_RT5650_MCLK_EXTERNAL = 0, + MT8173_RT5650_MCLK_INTERNAL, +}; + +struct mt8173_rt5650_platform_data { + enum mt8173_rt5650_mclk pll_from; + /* 0 = external oscillator; 1 = internal source from mt8173 */ +}; + +static struct mt8173_rt5650_platform_data mt8173_rt5650_priv = { + .pll_from = MT8173_RT5650_MCLK_EXTERNAL, +}; + static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL), @@ -54,13 +68,29 @@ static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int mclk_clock; int i, ret; + switch (mt8173_rt5650_priv.pll_from) { + case MT8173_RT5650_MCLK_EXTERNAL: + /* mclk = 12.288M */ + mclk_clock = MCLK_FOR_CODECS; + break; + case MT8173_RT5650_MCLK_INTERNAL: + /* mclk = sampling rate*256 */ + mclk_clock = params_rate(params) * 256; + break; + default: + /* mclk = 12.288M */ + mclk_clock = MCLK_FOR_CODECS; + break; + } + for (i = 0; i < rtd->num_codecs; i++) { struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; - /* pll from mclk 12.288M */ - ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS, + /* pll from mclk */ + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, mclk_clock, params_rate(params) * 512); if (ret) return ret; @@ -243,6 +273,17 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) mt8173_rt5650_codecs[1].dai_name = codec_capture_dai; } + if (device_property_present(&pdev->dev, "mediatek,mclk")) { + ret = device_property_read_u32(&pdev->dev, + "mediatek,mclk", + &mt8173_rt5650_priv.pll_from); + if (ret) { + dev_err(&pdev->dev, + "%s snd_soc_register_card fail %d\n", + __func__, ret); + } + } + card->dev = &pdev->dev; platform_set_drvdata(pdev, card); -- cgit v1.3-14-g43fede From 64bf55a72f550ad33f4053493717f51efe632e9f Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 31 May 2016 16:50:23 +0530 Subject: cpufreq: Unexport cpufreq_frequency_table_cpuinfo() All cpufreq drivers with a freq-table are migrated to use cpufreq_table_validate_and_show() long back and the routine cpufreq_frequency_table_cpuinfo() isn't used outside of cpufreq core now. Unexport it and update Documentation as well. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/core.txt | 4 ++-- Documentation/cpu-freq/cpu-drivers.txt | 2 +- drivers/cpufreq/freq_table.c | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/cpu-freq/core.txt b/Documentation/cpu-freq/core.txt index ba78e7c2a069..4bc7287806de 100644 --- a/Documentation/cpu-freq/core.txt +++ b/Documentation/cpu-freq/core.txt @@ -96,7 +96,7 @@ new - new frequency For details about OPP, see Documentation/power/opp.txt dev_pm_opp_init_cpufreq_table - cpufreq framework typically is initialized with - cpufreq_frequency_table_cpuinfo which is provided with the list of + cpufreq_table_validate_and_show() which is provided with the list of frequencies that are available for operation. This function provides a ready to use conversion routine to translate the OPP layer's internal information about the available frequencies into a format readily @@ -110,7 +110,7 @@ dev_pm_opp_init_cpufreq_table - cpufreq framework typically is initialized with /* Do things */ r = dev_pm_opp_init_cpufreq_table(dev, &freq_table); if (!r) - cpufreq_frequency_table_cpuinfo(policy, freq_table); + cpufreq_table_validate_and_show(policy, freq_table); /* Do other things */ } diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index 14f4e6336d88..decbb8cb5573 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -231,7 +231,7 @@ if you want to skip one entry in the table, set the frequency to CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending order. -By calling cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, +By calling cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); the cpuinfo.min_freq and cpuinfo.max_freq values are detected, and policy->min and policy->max are set to the same values. This is diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index a8f1daffc9bc..4e5c5dbfed7a 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -63,8 +63,6 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, else return 0; } -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo); - int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) -- cgit v1.3-14-g43fede From decba6d47869f3b5f057df5add52ece92d8e3d22 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 31 May 2016 10:23:02 -0700 Subject: mtd: brcmnand: Add v7.2 controller support The 7.2 controller differs in a few area compared to its predecssor (7.1): - NAND scrambler, which we are not using just yet - higher ECC levels (up to 120 bits) per 1KB data blocks, also not supported yet - up to 128B OOB This patch adds the necessary code to support such a controller generation and updates the Device Tree binding. Signed-off-by: Florian Fainelli Acked-by: Kamal Dasu Acked-by: Rob Herring Signed-off-by: Boris Brezillon --- .../devicetree/bindings/mtd/brcm,brcmnand.txt | 1 + drivers/mtd/nand/brcmnand/brcmnand.c | 91 ++++++++++++++++++---- 2 files changed, 78 insertions(+), 14 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt index 7066597c9a81..b40f3a492800 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt @@ -27,6 +27,7 @@ Required properties: brcm,brcmnand-v6.2 brcm,brcmnand-v7.0 brcm,brcmnand-v7.1 + brcm,brcmnand-v7.2 brcm,brcmnand - reg : the register start and length for NAND register region. (optional) Flash DMA register range (if present) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index b76ad7c0144f..0a54a0f5a4b1 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -340,6 +340,36 @@ static const u16 brcmnand_regs_v71[] = { [BRCMNAND_FC_BASE] = 0x400, }; +/* BRCMNAND v7.2 */ +static const u16 brcmnand_regs_v72[] = { + [BRCMNAND_CMD_START] = 0x04, + [BRCMNAND_CMD_EXT_ADDRESS] = 0x08, + [BRCMNAND_CMD_ADDRESS] = 0x0c, + [BRCMNAND_INTFC_STATUS] = 0x14, + [BRCMNAND_CS_SELECT] = 0x18, + [BRCMNAND_CS_XOR] = 0x1c, + [BRCMNAND_LL_OP] = 0x20, + [BRCMNAND_CS0_BASE] = 0x50, + [BRCMNAND_CS1_BASE] = 0, + [BRCMNAND_CORR_THRESHOLD] = 0xdc, + [BRCMNAND_CORR_THRESHOLD_EXT] = 0xe0, + [BRCMNAND_UNCORR_COUNT] = 0xfc, + [BRCMNAND_CORR_COUNT] = 0x100, + [BRCMNAND_CORR_EXT_ADDR] = 0x10c, + [BRCMNAND_CORR_ADDR] = 0x110, + [BRCMNAND_UNCORR_EXT_ADDR] = 0x114, + [BRCMNAND_UNCORR_ADDR] = 0x118, + [BRCMNAND_SEMAPHORE] = 0x150, + [BRCMNAND_ID] = 0x194, + [BRCMNAND_ID_EXT] = 0x198, + [BRCMNAND_LL_RDATA] = 0x19c, + [BRCMNAND_OOB_READ_BASE] = 0x200, + [BRCMNAND_OOB_READ_10_BASE] = 0, + [BRCMNAND_OOB_WRITE_BASE] = 0x400, + [BRCMNAND_OOB_WRITE_10_BASE] = 0, + [BRCMNAND_FC_BASE] = 0x600, +}; + enum brcmnand_cs_reg { BRCMNAND_CS_CFG_EXT = 0, BRCMNAND_CS_CFG, @@ -435,7 +465,9 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl) } /* Register offsets */ - if (ctrl->nand_version >= 0x0701) + if (ctrl->nand_version >= 0x0702) + ctrl->reg_offsets = brcmnand_regs_v72; + else if (ctrl->nand_version >= 0x0701) ctrl->reg_offsets = brcmnand_regs_v71; else if (ctrl->nand_version >= 0x0600) ctrl->reg_offsets = brcmnand_regs_v60; @@ -480,7 +512,9 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl) } /* Maximum spare area sector size (per 512B) */ - if (ctrl->nand_version >= 0x0600) + if (ctrl->nand_version >= 0x0702) + ctrl->max_oob = 128; + else if (ctrl->nand_version >= 0x0600) ctrl->max_oob = 64; else if (ctrl->nand_version >= 0x0500) ctrl->max_oob = 32; @@ -583,14 +617,20 @@ static void brcmnand_wr_corr_thresh(struct brcmnand_host *host, u8 val) enum brcmnand_reg reg = BRCMNAND_CORR_THRESHOLD; int cs = host->cs; - if (ctrl->nand_version >= 0x0600) + if (ctrl->nand_version >= 0x0702) + bits = 7; + else if (ctrl->nand_version >= 0x0600) bits = 6; else if (ctrl->nand_version >= 0x0500) bits = 5; else bits = 4; - if (ctrl->nand_version >= 0x0600) { + if (ctrl->nand_version >= 0x0702) { + if (cs >= 4) + reg = BRCMNAND_CORR_THRESHOLD_EXT; + shift = (cs % 4) * bits; + } else if (ctrl->nand_version >= 0x0600) { if (cs >= 5) reg = BRCMNAND_CORR_THRESHOLD_EXT; shift = (cs % 5) * bits; @@ -631,19 +671,28 @@ enum { static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) { - if (ctrl->nand_version >= 0x0600) + if (ctrl->nand_version >= 0x0702) + return GENMASK(7, 0); + else if (ctrl->nand_version >= 0x0600) return GENMASK(6, 0); else return GENMASK(5, 0); } #define NAND_ACC_CONTROL_ECC_SHIFT 16 +#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) { u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; - return mask << NAND_ACC_CONTROL_ECC_SHIFT; + mask <<= NAND_ACC_CONTROL_ECC_SHIFT; + + /* v7.2 includes additional ECC levels */ + if (ctrl->nand_version >= 0x0702) + mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT; + + return mask; } static void brcmnand_set_ecc_enabled(struct brcmnand_host *host, int en) @@ -667,7 +716,9 @@ static void brcmnand_set_ecc_enabled(struct brcmnand_host *host, int en) static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl) { - if (ctrl->nand_version >= 0x0600) + if (ctrl->nand_version >= 0x0702) + return 9; + else if (ctrl->nand_version >= 0x0600) return 7; else if (ctrl->nand_version >= 0x0500) return 6; @@ -773,10 +824,16 @@ enum brcmnand_llop_type { * Internal support functions ***********************************************************************/ -static inline bool is_hamming_ecc(struct brcmnand_cfg *cfg) +static inline bool is_hamming_ecc(struct brcmnand_controller *ctrl, + struct brcmnand_cfg *cfg) { - return cfg->sector_size_1k == 0 && cfg->spare_area_size == 16 && - cfg->ecc_level == 15; + if (ctrl->nand_version <= 0x0701) + return cfg->sector_size_1k == 0 && cfg->spare_area_size == 16 && + cfg->ecc_level == 15; + else + return cfg->sector_size_1k == 0 && ((cfg->spare_area_size == 16 && + cfg->ecc_level == 15) || + (cfg->spare_area_size == 28 && cfg->ecc_level == 16)); } /* @@ -931,7 +988,7 @@ static int brcmstb_choose_ecc_layout(struct brcmnand_host *host) if (p->sector_size_1k) ecc_level <<= 1; - if (is_hamming_ecc(p)) { + if (is_hamming_ecc(host->ctrl, p)) { ecc->bytes = 3 * sectors; mtd_set_ooblayout(mtd, &brcmnand_hamming_ooblayout_ops); return 0; @@ -1857,7 +1914,8 @@ static int brcmnand_set_cfg(struct brcmnand_host *host, return 0; } -static void brcmnand_print_cfg(char *buf, struct brcmnand_cfg *cfg) +static void brcmnand_print_cfg(struct brcmnand_host *host, + char *buf, struct brcmnand_cfg *cfg) { buf += sprintf(buf, "%lluMiB total, %uKiB blocks, %u%s pages, %uB OOB, %u-bit", @@ -1868,7 +1926,7 @@ static void brcmnand_print_cfg(char *buf, struct brcmnand_cfg *cfg) cfg->spare_area_size, cfg->device_width); /* Account for Hamming ECC and for BCH 512B vs 1KiB sectors */ - if (is_hamming_ecc(cfg)) + if (is_hamming_ecc(host->ctrl, cfg)) sprintf(buf, ", Hamming ECC"); else if (cfg->sector_size_1k) sprintf(buf, ", BCH-%u (1KiB sector)", cfg->ecc_level << 1); @@ -1987,7 +2045,7 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) brcmnand_set_ecc_enabled(host, 1); - brcmnand_print_cfg(msg, cfg); + brcmnand_print_cfg(host, msg, cfg); dev_info(ctrl->dev, "detected %s\n", msg); /* Configure ACC_CONTROL */ @@ -1995,6 +2053,10 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) tmp = nand_readreg(ctrl, offs); tmp &= ~ACC_CONTROL_PARTIAL_PAGE; tmp &= ~ACC_CONTROL_RD_ERASED; + + /* We need to turn on Read from erased paged protected by ECC */ + if (ctrl->nand_version >= 0x0702) + tmp |= ACC_CONTROL_RD_ERASED; tmp &= ~ACC_CONTROL_FAST_PGM_RDIN; if (ctrl->features & BRCMNAND_HAS_PREFETCH) { /* @@ -2195,6 +2257,7 @@ static const struct of_device_id brcmnand_of_match[] = { { .compatible = "brcm,brcmnand-v6.2" }, { .compatible = "brcm,brcmnand-v7.0" }, { .compatible = "brcm,brcmnand-v7.1" }, + { .compatible = "brcm,brcmnand-v7.2" }, {}, }; MODULE_DEVICE_TABLE(of, brcmnand_of_match); -- cgit v1.3-14-g43fede From 16e161c8c67ac3b27cfc096cf07af9bceb144707 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Jun 2016 14:59:18 +0200 Subject: doc/sphinx: Stop touching state_machine internals Instead of just forcefully inserting our kernel-doc input and letting the state machine stumble over it the recommended way is to create ViewList, parse that and then return the list of parsed nodes. Suggested by Jani. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 9fc2c27916a9..bd422870101e 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -32,6 +32,7 @@ import subprocess import sys from docutils import nodes, statemachine +from docutils.statemachine import ViewList from docutils.parsers.rst import directives from sphinx.util.compat import Directive @@ -92,8 +93,14 @@ class KernelDocDirective(Directive): sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) - self.state_machine.insert_input(lines, source) - return [] + result = ViewList(lines, source) + + node = nodes.section() + node.document = self.state.document + self.state.nested_parse(result, self.content_offset, node) + + return node.children + except Exception as e: env.app.warn('kernel-doc \'%s\' processing failed with: %s' % (" ".join(cmd), str(e))) -- cgit v1.3-14-g43fede From 6a8d73e2859df06540d37877b1c1a0c9b5d11292 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 24 May 2016 15:31:25 +0200 Subject: media: s5p-mfc: use generic reserved memory bindings Use generic reserved memory bindings and mark old, custom properties as obsoleted. Signed-off-by: Marek Szyprowski Reviewed-by: Javier Martinez Canillas Acked-by: Rob Herring Acked-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- .../devicetree/bindings/media/s5p-mfc.txt | 39 +++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt index 2d5787eac91a..92c94f5ecbf1 100644 --- a/Documentation/devicetree/bindings/media/s5p-mfc.txt +++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt @@ -21,15 +21,18 @@ Required properties: - clock-names : from common clock binding: must contain "mfc", corresponding to entry in the clocks property. - - samsung,mfc-r : Base address of the first memory bank used by MFC - for DMA contiguous memory allocation and its size. - - - samsung,mfc-l : Base address of the second memory bank used by MFC - for DMA contiguous memory allocation and its size. - Optional properties: - power-domains : power-domain property defined with a phandle to respective power domain. + - memory-region : from reserved memory binding: phandles to two reserved + memory regions, first is for "left" mfc memory bus interfaces, + second if for the "right" mfc memory bus, used when no SYSMMU + support is available + +Obsolete properties: + - samsung,mfc-r, samsung,mfc-l : support removed, please use memory-region + property instead + Example: SoC specific DT entry: @@ -43,9 +46,29 @@ mfc: codec@13400000 { clock-names = "mfc"; }; +Reserved memory specific DT entry for given board (see reserved memory binding +for more information): + +reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mfc_left: region@51000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x51000000 0x800000>; + }; + + mfc_right: region@43000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x43000000 0x800000>; + }; +}; + Board specific DT entry: codec@13400000 { - samsung,mfc-r = <0x43000000 0x800000>; - samsung,mfc-l = <0x51000000 0x800000>; + memory-region = <&mfc_left>, <&mfc_right>; }; -- cgit v1.3-14-g43fede From aca83380e33e6bba646852626640a8188a369a72 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 31 May 2016 23:11:13 +0200 Subject: drm/gpu.tmpl: Don't forget to rename the include directives, too We need to get folks to run $ make htmldocs more often and actually check the output. With the fancy new sphinx stuff there's hopefully no more excuses. Fixes: 286dbb8d5d80 ("drm/atomic: Rename async parameter to nonblocking.") Cc: Maarten Lankhorst Acked-by: Liviu Dudau Acked-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1464729075-22243-4-git-send-email-daniel.vetter@ffwll.ch --- Documentation/DocBook/gpu.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index b3a04b521b22..dac18b4ff090 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1570,7 +1570,7 @@ void intel_crt_init(struct drm_device *dev) Implementing Asynchronous Atomic Commit -!Pdrivers/gpu/drm/drm_atomic_helper.c implementing async commit +!Pdrivers/gpu/drm/drm_atomic_helper.c implementing nonblocking commit Atomic State Reset and Initialization -- cgit v1.3-14-g43fede From fac8434dab9645905d0f1f6baaa0f2e27daca435 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 May 2016 02:28:36 -0400 Subject: Documentation: Fix some grammar mistakes in sync_file.txt There are two sentences in the Sync File documentation where the english is a little off. This patch is an attempt to fix these. Signed-off-by: Javier Martinez Canillas Reviewed-by: Gustavo Padovan Signed-off-by: Jonathan Corbet --- Documentation/sync_file.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sync_file.txt b/Documentation/sync_file.txt index eaf8297dbca2..e8e2ebafe5fa 100644 --- a/Documentation/sync_file.txt +++ b/Documentation/sync_file.txt @@ -6,8 +6,8 @@ This document serves as a guide for device drivers writers on what the sync_file API is, and how drivers can support it. Sync file is the carrier of -the fences(struct fence) that needs to synchronized between drivers or across -process boundaries. +the fences(struct fence) that are needed to synchronize between drivers or +across process boundaries. The sync_file API is meant to be used to send and receive fence information to/from userspace. It enables userspace to do explicit fencing, where instead @@ -32,7 +32,7 @@ in-fences and out-fences Sync files can go either to or from userspace. When a sync_file is sent from the driver to userspace we call the fences it contains 'out-fences'. They are related to a buffer that the driver is processing or is going to process, so -the driver an create out-fence to be able to notify, through fence_signal(), +the driver creates an out-fence to be able to notify, through fence_signal(), when it has finished using (or processing) that buffer. Out-fences are fences that the driver creates. -- cgit v1.3-14-g43fede From 3610a2add39365a0f153154c60169a66c616d50f Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Thu, 19 May 2016 21:54:51 -0700 Subject: mpssd: fix buffer overflow warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compilation emits a warning in function ‘snprintf’, inlined from ‘set_cmdline’ at ../Documentation/mic/mpssd/mpssd.c:1541:9: /usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: warning: call to __builtin___snprintf_chk will always overflow destination buffer This was introduced in commit f4a66c204482 ("misc: mic: Update MIC host daemon with COSM changes") and is fixed by reverting the changes to the size argument of these snprintf statements. Cc: Ashutosh Dixit Signed-off-by: Mike Danese Signed-off-by: Jonathan Corbet --- Documentation/mic/mpssd/mpssd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c index 30fb842a976d..49db1def1721 100644 --- a/Documentation/mic/mpssd/mpssd.c +++ b/Documentation/mic/mpssd/mpssd.c @@ -1538,9 +1538,9 @@ set_cmdline(struct mic_info *mic) len = snprintf(buffer, PATH_MAX, "clocksource=tsc highres=off nohz=off "); - len += snprintf(buffer + len, PATH_MAX, + len += snprintf(buffer + len, PATH_MAX - len, "cpufreq_on;corec6_off;pc3_off;pc6_off "); - len += snprintf(buffer + len, PATH_MAX, + len += snprintf(buffer + len, PATH_MAX - len, "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0", mic->id + 1); -- cgit v1.3-14-g43fede From d81749ea8b1537a382535983a269fc69c696fa0e Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 23 May 2016 13:37:58 -0700 Subject: doc: clarify that trace_events= takes a comma-separated list It took me browsing through the source code to determine that I was, indeed, using the wrong delimiter in my command lines. So I might as well document it for the next person. Signed-off-by: Brian Norris Acked-by: Steven Rostedt Signed-off-by: Jonathan Corbet --- Documentation/kernel-parameters.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..a2a662d4da83 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3992,8 +3992,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. trace_event=[event-list] [FTRACE] Set and start specified trace events in order - to facilitate early boot debugging. - See also Documentation/trace/events.txt + to facilitate early boot debugging. The event-list is a + comma separated list of trace events to enable. See + also Documentation/trace/events.txt trace_options=[option-list] [FTRACE] Enable or disable tracer options at boot. -- cgit v1.3-14-g43fede From 49e48419ad0f1dd91f04bf932a4becae3cde514f Mon Sep 17 00:00:00 2001 From: Andy Deng Date: Sun, 29 May 2016 23:45:10 +0800 Subject: Documentation/zh_CN: update Chinese version CodingStyle Chinese version CodingStyle is a little outdate, it should be updated. This patch sync with the latest CodingStyle of all changes, new chapters (chapter 19 and chapter 20) have been translated. Signed-off-by: Andy Deng Signed-off-by: Jonathan Corbet --- Documentation/zh_CN/CodingStyle | 581 ++++++++++++++++++++++++---------------- 1 file changed, 350 insertions(+), 231 deletions(-) (limited to 'Documentation') diff --git a/Documentation/zh_CN/CodingStyle b/Documentation/zh_CN/CodingStyle index 654afd72eb24..bbb9d6ae05ca 100644 --- a/Documentation/zh_CN/CodingStyle +++ b/Documentation/zh_CN/CodingStyle @@ -24,34 +24,33 @@ Documentation/CodingStyle的中文翻译 Linux内核代码风格 -这是一个简短的文档,描述了linux内核的首选代码风格。代码风格是因人而异的,而且我 -不愿意把我的观点强加给任何人,不过这里所讲述的是我必须要维护的代码所遵守的风格, -并且我也希望绝大多数其他代码也能遵守这个风格。请在写代码时至少考虑一下本文所述的 -风格。 +这是一个简短的文档,描述了 linux 内核的首选代码风格。代码风格是因人而异的,而且我 +不愿意把自己的观点强加给任何人,但这就像我去做任何事情都必须遵循的原则那样,我也 +希望在绝大多数事上保持这种的态度。请(在写代码时)至少考虑一下这里的代码风格。 -首先,我建议你打印一份GNU代码规范,然后不要读它。烧了它,这是一个具有重大象征性 -意义的动作。 +首先,我建议你打印一份 GNU 代码规范,然后不要读。烧了它,这是一个具有重大象征性意义 +的动作。 不管怎样,现在我们开始: - 第一章:缩进 + 第一章:缩进 -制表符是8个字符,所以缩进也是8个字符。有些异端运动试图将缩进变为4(乃至2)个字符 -深,这几乎相当于尝试将圆周率的值定义为3。 +制表符是 8 个字符,所以缩进也是 8 个字符。有些异端运动试图将缩进变为 4(甚至 2!) +个字符深,这几乎相当于尝试将圆周率的值定义为 3。 理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的屏幕 -连续看了20小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。 +连续看了 20 小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。 -现在,有些人会抱怨8个字符的缩进会使代码向右边移动的太远,在80个字符的终端屏幕上 -就很难读这样的代码。这个问题的答案是,如果你需要3级以上的缩进,不管用何种方式你 +现在,有些人会抱怨 8 个字符的缩进会使代码向右边移动的太远,在 80 个字符的终端屏幕上 +就很难读这样的代码。这个问题的答案是,如果你需要 3 级以上的缩进,不管用何种方式你 的代码已经有问题了,应该修正你的程序。 -简而言之,8个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的 +简而言之,8 个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的 时候可以给你警告。留心这个警告。 -在switch语句中消除多级缩进的首选的方式是让“switch”和从属于它的“case”标签对齐于同 -一列,而不要“两次缩进”“case”标签。比如: +在 switch 语句中消除多级缩进的首选的方式是让 “switch” 和从属于它的 “case” 标签 +对齐于同一列,而不要 “两次缩进” “case” 标签。比如: switch (suffix) { case 'G': @@ -70,7 +69,6 @@ Documentation/CodingStyle的中文翻译 break; } - 不要把多个语句放在一行里,除非你有什么东西要隐藏: if (condition) do_this; @@ -79,7 +77,7 @@ Documentation/CodingStyle的中文翻译 也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读的表 达式。 -除了注释、文档和Kconfig之外,不要使用空格来缩进,前面的例子是例外,是有意为之。 +除了注释、文档和 Kconfig 之外,不要使用空格来缩进,前面的例子是例外,是有意为之。 选用一个好的编辑器,不要在行尾留空格。 @@ -88,27 +86,18 @@ Documentation/CodingStyle的中文翻译 代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。 -每一行的长度的限制是80列,我们强烈建议您遵守这个惯例。 +每一行的长度的限制是 80 列,我们强烈建议您遵守这个惯例。 -长于80列的语句要打散成有意义的片段。每个片段要明显短于原来的语句,而且放置的位置 -也明显的靠右。同样的规则也适用于有很长参数列表的函数头。长字符串也要打散成较短的 -字符串。唯一的例外是超过80列可以大幅度提高可读性并且不会隐藏信息的情况。 - -void fun(int a, int b, int c) -{ - if (condition) - printk(KERN_WARNING "Warning this is a long printk with " - "3 parameters a: %u b: %u " - "c: %u \n", a, b, c); - else - next_statement; -} +长于 80 列的语句要打散成有意义的片段。除非超过 80 列能显著增加可读性,并且不会隐藏 +信息。子片段要明显短于母片段,并明显靠右。这同样适用于有着很长参数列表的函数头。 +然而,绝对不要打散对用户可见的字符串,例如 printk 信息,因为这将导致无法 grep 这些 +信息。 第三章:大括号和空格的放置 C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放置策 -略并没有多少技术上的原因,不过首选的方式,就像Kernighan和Ritchie展示给我们的,是 -把起始大括号放在行尾,而把结束大括号放在行首,所以: +略并没有多少技术上的原因,不过首选的方式,就像 Kernighan 和 Ritchie 展示给我们的, +是把起始大括号放在行尾,而把结束大括号放在行首,所以: if (x is true) { we do y @@ -134,12 +123,12 @@ C语言风格中另外一个常见问题是大括号的放置。和缩进大小 body of function } -全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道( -a)K&R是_正确的_,并且(b)K&R是正确的。此外,不管怎样函数都是特殊的(在C语言中 -,函数是不能嵌套的)。 +全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道 +(a) K&R 是 _正确的_,并且 (b) K&R 是正确的。此外,不管怎样函数都是特殊的(C +函数是不能嵌套的)。 -注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是do语句中的 -“while”或者if语句中的“else”,像这样: +注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是 do 语句中的 +“while” 或者 if 语句中的 “else”,像这样: do { body of do-loop @@ -158,41 +147,50 @@ a)K&R是_正确的_,并且(b)K&R是正确的。此外,不管怎样函 理由:K&R。 也请注意这种大括号的放置方式也能使空(或者差不多空的)行的数量最小化,同时不失可 -读性。因此,由于你的屏幕上的新行是不可再生资源(想想25行的终端屏幕),你将会有更 +读性。因此,由于你的屏幕上的新行是不可再生资源(想想 25 行的终端屏幕),你将会有更 多的空行来放置注释。 当只有一个单独的语句的时候,不用加不必要的大括号。 -if (condition) - action(); + if (condition) + action(); + +和 + + if (condition) + do_this(); + else + do_that(); -这点不适用于本身为某个条件语句的一个分支的单独语句。这时需要在两个分支里都使用大 -括号。 +这并不适用于只有一个条件分支是单语句的情况;这时所有分支都要使用大括号: -if (condition) { - do_this(); - do_that(); -} else { - otherwise(); -} + if (condition) { + do_this(); + do_that(); + } else { + otherwise(); + } 3.1:空格 -Linux内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后 -要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__,这些关键字 -某些程度上看起来更像函数(它们在Linux里也常常伴随小括号而使用,尽管在C语言里这样 -的小括号不是必需的,就像“struct fileinfo info”声明过后的“sizeof info”)。 +Linux 内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后 +要加一个空格。值得注意的例外是 sizeof、typeof、alignof 和 __attribute__,这些 +关键字某些程度上看起来更像函数(它们在 Linux 里也常常伴随小括号而使用,尽管在 C 里 +这样的小括号不是必需的,就像 “struct fileinfo info” 声明过后的 “sizeof info”)。 所以在这些关键字之后放一个空格: + if, switch, case, for, do, while -但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如, + +但是不要在 sizeof、typeof、alignof 或者 __attribute__ 这些关键字之后放空格。例如, + s = sizeof(struct file); 不要在小括号里的表达式两侧加空格。这是一个反例: s = sizeof( struct file ); -当声明指针类型或者返回指针类型的函数时,“*”的首选使用方式是使之靠近变量名或者函 +当声明指针类型或者返回指针类型的函数时,“*” 的首选使用方式是使之靠近变量名或者函 数名,而不是靠近类型名。例子: char *linux_banner; @@ -204,15 +202,18 @@ Linux内核的空格使用方式(主要)取决于它是用于函数还是关 = + - < > * / % | & ^ <= >= == != ? : 但是一元操作符后不要加空格: + & * + - ~ ! sizeof typeof alignof __attribute__ defined 后缀自加和自减一元操作符前不加空格: + ++ -- 前缀自加和自减一元操作符后不加空格: + ++ -- -“.”和“->”结构体成员操作符前后不加空格。 +‘.’ 和 “->” 结构体成员操作符前后不加空格。 不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后你 就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码,有些编辑器就不 @@ -225,23 +226,23 @@ Linux内核的空格使用方式(主要)取决于它是用于函数还是关 第四章:命名 -C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal程序员不同,C程序员不使 -用类似ThisVariableIsATemporaryCounter这样华丽的名字。C程序员会称那个变量为“tmp” -,这样写起来会更容易,而且至少不会令其难于理解。 +C是一个简朴的语言,你的命名也应该这样。和 Modula-2 和 Pascal 程序员不同,C 程序员 +不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C 程序员会称那个变量 +为 “tmp”,这样写起来会更容易,而且至少不会令其难于理解。 不过,虽然混用大小写的名字是不提倡使用的,但是全局变量还是需要一个具描述性的名字 -。称一个全局函数为“foo”是一个难以饶恕的错误。 +。称一个全局函数为 “foo” 是一个难以饶恕的错误。 全局变量(只有当你真正需要它们的时候再用它)需要有一个具描述性的名字,就像全局函 -数。如果你有一个可以计算活动用户数量的函数,你应该叫它“count_active_users()”或者 -类似的名字,你不应该叫它“cntuser()”。 +数。如果你有一个可以计算活动用户数量的函数,你应该叫它 “count_active_users()” +或者类似的名字,你不应该叫它 “cntuser()”。 在函数名中包含函数类型(所谓的匈牙利命名法)是脑子出了问题——编译器知道那些类型而 且能够检查那些类型,这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题的程序。 本地变量名应该简短,而且能够表达相关的含义。如果你有一些随机的整数型的循环计数器 -,它应该被称为“i”。叫它“loop_counter”并无益处,如果它没有被误解的可能的话。类似 -的,“tmp”可以用来称呼任意类型的临时变量。 +,它应该被称为 “i”。叫它 “loop_counter” 并无益处,如果它没有被误解的可能的话。 +类似的,“tmp” 可以用来称呼任意类型的临时变量。 如果你怕混淆了你的本地变量名,你就遇到另一个问题了,叫做函数增长荷尔蒙失衡综合症 。请看第六章(函数)。 @@ -249,9 +250,9 @@ C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal 第五章:Typedef -不要使用类似“vps_t”之类的东西。 +不要使用类似 “vps_t” 之类的东西。 -对结构体和指针使用typedef是一个错误。当你在代码里看到: +对结构体和指针使用 typedef 是一个错误。当你在代码里看到: vps_t a; @@ -261,91 +262,91 @@ C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal struct virtual_container *a; -你就知道“a”是什么了。 +你就知道 “a” 是什么了。 -很多人认为typedef“能提高可读性”。实际不是这样的。它们只在下列情况下有用: +很多人认为 typedef “能提高可读性”。实际不是这样的。它们只在下列情况下有用: - (a) 完全不透明的对象(这种情况下要主动使用typedef来隐藏这个对象实际上是什么)。 + (a) 完全不透明的对象(这种情况下要主动使用 typedef 来隐藏这个对象实际上是什么)。 - 例如:“pte_t”等不透明对象,你只能用合适的访问函数来访问它们。 + 例如:“pte_t” 等不透明对象,你只能用合适的访问函数来访问它们。 - 注意!不透明性和“访问函数”本身是不好的。我们使用pte_t等类型的原因在于真的是 + 注意!不透明性和“访问函数”本身是不好的。我们使用 pte_t 等类型的原因在于真的是 完全没有任何共用的可访问信息。 - (b) 清楚的整数类型,如此,这层抽象就可以帮助消除到底是“int”还是“long”的混淆。 + (b) 清楚的整数类型,如此,这层抽象就可以帮助消除到底是 “int” 还是 “long” 的混淆。 - u8/u16/u32是完全没有问题的typedef,不过它们更符合类别(d)而不是这里。 + u8/u16/u32 是完全没有问题的 typedef,不过它们更符合类别 (d) 而不是这里。 - 再次注意!要这样做,必须事出有因。如果某个变量是“unsigned long“,那么没有必要 + 再次注意!要这样做,必须事出有因。如果某个变量是 “unsigned long“,那么没有必要 typedef unsigned long myflags_t; - 不过如果有一个明确的原因,比如它在某种情况下可能会是一个“unsigned int”而在 - 其他情况下可能为“unsigned long”,那么就不要犹豫,请务必使用typedef。 + 不过如果有一个明确的原因,比如它在某种情况下可能会是一个 “unsigned int” 而在 + 其他情况下可能为 “unsigned long”,那么就不要犹豫,请务必使用 typedef。 (c) 当你使用sparse按字面的创建一个新类型来做类型检查的时候。 (d) 和标准C99类型相同的类型,在某些例外的情况下。 - 虽然让眼睛和脑筋来适应新的标准类型比如“uint32_t”不需要花很多时间,可是有些 + 虽然让眼睛和脑筋来适应新的标准类型比如 “uint32_t” 不需要花很多时间,可是有些 人仍然拒绝使用它们。 - 因此,Linux特有的等同于标准类型的“u8/u16/u32/u64”类型和它们的有符号类型是被 + 因此,Linux 特有的等同于标准类型的 “u8/u16/u32/u64” 类型和它们的有符号类型是被 允许的——尽管在你自己的新代码中,它们不是强制要求要使用的。 当编辑已经使用了某个类型集的已有代码时,你应该遵循那些代码中已经做出的选择。 (e) 可以在用户空间安全使用的类型。 - 在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的“u32” - 类型。因此,我们在与用户空间共享的所有结构体中使用__u32和类似的类型。 + 在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的 “u32” + 类型。因此,我们在与用户空间共享的所有结构体中使用 __u32 和类似的类型。 -可能还有其他的情况,不过基本的规则是永远不要使用typedef,除非你可以明确的应用上 +可能还有其他的情况,不过基本的规则是永远不要使用 typedef,除非你可以明确的应用上 述某个规则中的一个。 总的来说,如果一个指针或者一个结构体里的元素可以合理的被直接访问到,那么它们就不 -应该是一个typedef。 +应该是一个 typedef。 第六章:函数 函数应该简短而漂亮,并且只完成一件事情。函数应该可以一屏或者两屏显示完(我们都知 -道ISO/ANSI屏幕大小是80x24),只做一件事情,而且把它做好。 +道 ISO/ANSI 屏幕大小是 80x24),只做一件事情,而且把它做好。 一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以,如果你有一个理论上 -很简单的只有一个很长(但是简单)的case语句的函数,而且你需要在每个case里做很多很 -小的事情,这样的函数尽管很长,但也是可以的。 +很简单的只有一个很长(但是简单)的 case 语句的函数,而且你需要在每个 case 里做 +很多很小的事情,这样的函数尽管很长,但也是可以的。 不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能甚至 搞不清楚这个函数的目的,你应该严格的遵守前面提到的长度限制。使用辅助函数,并为之 取个具描述性的名字(如果你觉得它们的性能很重要的话,可以让编译器内联它们,这样的 效果往往会比你写一个复杂函数的效果要好。) -函数的另外一个衡量标准是本地变量的数量。此数量不应超过5-10个,否则你的函数就有 +函数的另外一个衡量标准是本地变量的数量。此数量不应超过 5-10 个,否则你的函数就有 问题了。重新考虑一下你的函数,把它分拆成更小的函数。人的大脑一般可以轻松的同时跟 -踪7个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你2 -个星期前做过的事情。 +踪 7 个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你 +2 个星期前做过的事情。 -在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的EXPORT*宏应该紧贴 +在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的 EXPORT* 宏应该紧贴 在它的结束大括号之下。比如: -int system_is_up(void) -{ - return system_state == SYSTEM_RUNNING; -} -EXPORT_SYMBOL(system_is_up); + int system_is_up(void) + { + return system_state == SYSTEM_RUNNING; + } + EXPORT_SYMBOL(system_is_up); -在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在Linux里这 +在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在 Linux 里这 是提倡的做法,因为这样可以很简单的给读者提供更多的有价值的信息。 第七章:集中的函数退出途径 -虽然被某些人声称已经过时,但是goto语句的等价物还是经常被编译器所使用,具体形式是 +虽然被某些人声称已经过时,但是 goto 语句的等价物还是经常被编译器所使用,具体形式是 无条件跳转指令。 -当一个函数从多个位置退出并且需要做一些通用的清理工作的时候,goto的好处就显现出来 -了。 +当一个函数从多个位置退出,并且需要做一些类似清理的常见操作时,goto 语句就很方便了。 +如果并不需要清理操作,那么直接 return 即可。 理由是: @@ -354,26 +355,37 @@ EXPORT_SYMBOL(system_is_up); - 可以避免由于修改时忘记更新某个单独的退出点而导致的错误 - 减轻了编译器的工作,无需删除冗余代码;) -int fun(int a) -{ - int result = 0; - char *buffer = kmalloc(SIZE); - - if (buffer == NULL) - return -ENOMEM; - - if (condition1) { - while (loop1) { - ... + int fun(int a) + { + int result = 0; + char *buffer; + + buffer = kmalloc(SIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + if (condition1) { + while (loop1) { + ... + } + result = 1; + goto out_buffer; } - result = 1; - goto out; + ... + out_buffer: + kfree(buffer); + return result; } - ... -out: - kfree(buffer); - return result; -} + +一个需要注意的常见错误是“一个 err 错误”,就像这样: + + err: + kfree(foo->bar); + kfree(foo); + return ret; + +这段代码的错误是,在某些退出路径上 “foo” 是 NULL。通常情况下,通过把它分离成两个 +错误标签 “err_bar:” 和 “err_foo:” 来修复这个错误。 第八章:注释 @@ -386,10 +398,10 @@ out: 加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么,也可以加上它做这 些事情的原因。 -当注释内核API函数时,请使用kernel-doc格式。请看 -Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc以获得详细信息。 +当注释内核API函数时,请使用 kernel-doc 格式。请看 +Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc 以获得详细信息。 -Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ...”注释。 +Linux的注释风格是 C89 “/* ... */” 风格。不要使用 C99 风格 “// ...” 注释。 长(多行)的首选注释风格是: @@ -402,6 +414,15 @@ Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ... * with beginning and ending almost-blank lines. */ +对于在 net/ 和 drivers/net/ 的文件,首选的长(多行)注释风格有些不同。 + + /* The preferred comment style for files in net/ and drivers/net + * looks like this. + * + * It is nearly the same as the generally preferred comment style, + * but there is no initial almost-blank line. + */ + 注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行应只 声明一个数据(不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据写一段 小注释来解释它们的用途了。 @@ -409,49 +430,63 @@ Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ... 第九章:你已经把事情弄糟了 -这没什么,我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你“GNU emacs”能 -自动帮你格式化C源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们 -想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在GNU emacs里打字永远不 -会创造出一个好程序)(译注:请参考Infinite Monkey Theorem) - -所以你要么放弃GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可 -以把下面这段粘贴到你的.emacs文件里。 - -(defun linux-c-mode () - "C mode with adjusted defaults for use with the Linux kernel." - (interactive) - (c-mode) - (c-set-style "K&R") - (setq tab-width 8) - (setq indent-tabs-mode t) - (setq c-basic-offset 8)) - -这样就定义了M-x linux-c-mode命令。当你hack一个模块的时候,如果你把字符串 --*- linux-c -*-放在头两行的某个位置,这个模式将会被自动调用。如果你希望在你修改 -/usr/src/linux里的文件时魔术般自动打开linux-c-mode的话,你也可能需要添加 - -(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode) - auto-mode-alist)) - -到你的.emacs文件里。 - -不过就算你尝试让emacs正确的格式化代码失败了,也并不意味着你失去了一切:还可以用“ -indent”。 - -不过,GNU indent也有和GNU emacs一样有问题的设定,所以你需要给它一些命令选项。不 -过,这还不算太糟糕,因为就算是GNU indent的作者也认同K&R的权威性(GNU的人并不是坏 -人,他们只是在这个问题上被严重的误导了),所以你只要给indent指定选项“-kr -i8” -(代表“K&R,8个字符缩进”),或者使用“scripts/Lindent”,这样就可以以最时髦的方式 +这没什么,我们都是这样。可能你的使用了很长时间 Unix 的朋友已经告诉你 “GNU emacs” 能 +自动帮你格式化 C 源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们 +想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在 GNU emacs 里打字永远不 +会创造出一个好程序)(译注:请参考 Infinite Monkey Theorem) + +所以你要么放弃 GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可 +以把下面这段粘贴到你的 .emacs 文件里。 + +(defun c-lineup-arglist-tabs-only (ignored) + "Line up argument lists by tabs, not spaces" + (let* ((anchor (c-langelem-pos c-syntactic-element)) + (column (c-langelem-2nd-pos c-syntactic-element)) + (offset (- (1+ column) anchor)) + (steps (floor offset c-basic-offset))) + (* (max steps 1) + c-basic-offset))) + +(add-hook 'c-mode-common-hook + (lambda () + ;; Add kernel style + (c-add-style + "linux-tabs-only" + '("linux" (c-offsets-alist + (arglist-cont-nonempty + c-lineup-gcc-asm-reg + c-lineup-arglist-tabs-only)))))) + +(add-hook 'c-mode-hook + (lambda () + (let ((filename (buffer-file-name))) + ;; Enable kernel mode for the appropriate files + (when (and filename + (string-match (expand-file-name "~/src/linux-trees") + filename)) + (setq indent-tabs-mode t) + (setq show-trailing-whitespace t) + (c-set-style "linux-tabs-only"))))) + +这会让 emacs 在 ~/src/linux-trees 目录下的 C 源文件获得更好的内核代码风格。 + +不过就算你尝试让 emacs 正确的格式化代码失败了,也并不意味着你失去了一切:还可以用 +“indent”。 + +不过,GNU indent 也有和 GNU emacs 一样有问题的设定,所以你需要给它一些命令选项。不 +过,这还不算太糟糕,因为就算是 GNU indent 的作者也认同 K&R 的权威性(GNU 的人并不是 +坏人,他们只是在这个问题上被严重的误导了),所以你只要给 indent 指定选项 “-kr -i8” +(代表 “K&R,8 个字符缩进”),或者使用 “scripts/Lindent”,这样就可以以最时髦的方式 缩进源代码。 -“indent”有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过 -记住:“indent”不能修正坏的编程习惯。 +“indent” 有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过 +记住:“indent” 不能修正坏的编程习惯。 - 第十章:Kconfig配置文件 + 第十章:Kconfig 配置文件 -对于遍布源码树的所有Kconfig*配置文件来说,它们缩进方式与C代码相比有所不同。紧挨 -在“config”定义下面的行缩进一个制表符,帮助信息则再多缩进2个空格。比如: +对于遍布源码树的所有 Kconfig* 配置文件来说,它们缩进方式与 C 代码相比有所不同。紧挨 +在 “config” 定义下面的行缩进一个制表符,帮助信息则再多缩进 2 个空格。比如: config AUDIT bool "Auditing support" @@ -470,7 +505,7 @@ config ADFS_FS_RW depends on ADFS_FS ... -要查看配置文件的完整文档,请看Documentation/kbuild/kconfig-language.txt。 +要查看配置文件的完整文档,请看 Documentation/kbuild/kconfig-language.txt。 第十一章:数据结构 @@ -489,11 +524,11 @@ config ADFS_FS_RW 很多数据结构实际上有2级引用计数,它们通常有不同“类”的用户。子类计数器统计子类用 户的数量,每当子类计数器减至零时,全局计数器减一。 -这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users和mm_count) +这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users 和 mm_count) 和文件系统(“struct super_block”:s_count和s_active)中找到。 记住:如果另一个执行线索可以找到你的数据结构,但是这个数据结构没有引用计数器,这 -里几乎肯定是一个bug。 +里几乎肯定是一个 bug。 第十二章:宏,枚举和RTL @@ -508,102 +543,128 @@ config ADFS_FS_RW 一般的,如果能写成内联函数就不要写成像函数的宏。 -含有多个语句的宏应该被包含在一个do-while代码块里: +含有多个语句的宏应该被包含在一个 do-while 代码块里: -#define macrofun(a, b, c) \ - do { \ - if (a == 5) \ - do_this(b, c); \ - } while (0) + #define macrofun(a, b, c) \ + do { \ + if (a == 5) \ + do_this(b, c); \ + } while (0) 使用宏的时候应避免的事情: 1) 影响控制流程的宏: -#define FOO(x) \ - do { \ - if (blah(x) < 0) \ - return -EBUGGERED; \ - } while(0) + #define FOO(x) \ + do { \ + if (blah(x) < 0) \ + return -EBUGGERED; \ + } while (0) 非常不好。它看起来像一个函数,不过却能导致“调用”它的函数退出;不要打乱读者大脑里 的语法分析器。 2) 依赖于一个固定名字的本地变量的宏: -#define FOO(val) bar(index, val) + #define FOO(val) bar(index, val) 可能看起来像是个不错的东西,不过它非常容易把读代码的人搞糊涂,而且容易导致看起来 不相关的改动带来错误。 -3) 作为左值的带参数的宏: FOO(x) = y;如果有人把FOO变成一个内联函数的话,这种用 +3) 作为左值的带参数的宏: FOO(x) = y;如果有人把 FOO 变成一个内联函数的话,这种用 法就会出错了。 4) 忘记了优先级:使用表达式定义常量的宏必须将表达式置于一对小括号之内。带参数的 宏也要注意此类问题。 -#define CONSTANT 0x4000 -#define CONSTEXP (CONSTANT | 3) + #define CONSTANT 0x4000 + #define CONSTEXP (CONSTANT | 3) + +5) 在宏里定义类似函数的本地变量时命名冲突: -cpp手册对宏的讲解很详细。Gcc internals手册也详细讲解了RTL(译注:register + #define FOO(x) \ + ({ \ + typeof(x) ret; \ + ret = calc_ret(x); \ + (ret); \ + }) + +ret 是本地变量的通用名字 - __foo_ret 更不容易与一个已存在的变量冲突。 + +cpp 手册对宏的讲解很详细。gcc internals 手册也详细讲解了 RTL(译注:register transfer language),内核里的汇编语言经常用到它。 第十三章:打印内核消息 内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。不要 -用不规范的单词比如“dont”,而要用“do not”或者“don't”。保证这些信息简单、明了、无 -歧义。 +用不规范的单词比如 “dont”,而要用 “do not”或者 “don't”。保证这些信息简单、明了、 +无歧义。 内核信息不必以句号(译注:英文句号,即点)结束。 -在小括号里打印数字(%d)没有任何价值,应该避免这样做。 +在小括号里打印数字 (%d) 没有任何价值,应该避免这样做。 -里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的 -设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(), dev_warn(), -dev_info()等等。对于那些不和某个特定设备相关连的信息,定义了 -pr_debug()和pr_info()。 + 里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的 +设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(),dev_warn(), +dev_info() 等等。对于那些不和某个特定设备相关连的信息, 定义了 +pr_notice(),pr_info(),pr_warn(),pr_err() 和其他。 -写出好的调试信息可以是一个很大的挑战;当你写出来之后,这些信息在远程除错的时候 -就会成为极大的帮助。当DEBUG符号没有被定义的时候,这些信息不应该被编译进内核里 -(也就是说,默认地,它们不应该被包含在内)。如果你使用dev_dbg()或者pr_debug(), -就能自动达到这个效果。很多子系统拥有Kconfig选项来启用-DDEBUG。还有一个相关的惯例 -是使用VERBOSE_DEBUG来添加dev_vdbg()消息到那些已经由DEBUG启用的消息之上。 +写出好的调试信息可以是一个很大的挑战;一旦你写出后,这些信息在远程除错时能提供极大 +的帮助。然而打印调试信息的处理方式同打印非调试信息不同。其他 pr_XXX() 函数能无条件地 +打印,pr_debug() 却不;默认情况下它不会被编译,除非定义了 DEBUG 或设定了 +CONFIG_DYNAMIC_DEBUG。实际这同样是为了 dev_dbg(),一个相关约定是在一个已经开启了 +DEBUG 时,使用 VERBOSE_DEBUG 来添加 dev_vdbg()。 + +许多子系统拥有 Kconfig 调试选项来开启 -DDEBUG 在对应的 Makefile 里面;在其他 +情况下,特殊文件使用 #define DEBUG。当一条调试信息需要被无条件打印时,例如,如果 +已经包含一个调试相关的 #ifdef 条件,printk(KERN_DEBUG ...) 就可被使用。 第十四章:分配内存 -内核提供了下面的一般用途的内存分配函数:kmalloc(),kzalloc(),kcalloc()和 -vmalloc()。请参考API文档以获取有关它们的详细信息。 +内核提供了下面的一般用途的内存分配函数: +kmalloc(),kzalloc(),kmalloc_array(),kcalloc(),vmalloc() 和 vzalloc()。 +请参考 API 文档以获取有关它们的详细信息。 传递结构体大小的首选形式是这样的: p = kmalloc(sizeof(*p), ...); -另外一种传递方式中,sizeof的操作数是结构体的名字,这样会降低可读性,并且可能会引 -入bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的sizeof的结果不变。 +另外一种传递方式中,sizeof 的操作数是结构体的名字,这样会降低可读性,并且可能会引 +入 bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的 sizeof 的结果不变。 -强制转换一个void指针返回值是多余的。C语言本身保证了从void指针到其他任何指针类型 +强制转换一个 void 指针返回值是多余的。C 语言本身保证了从 void 指针到其他任何指针类型 的转换是没有问题的。 +分配一个数组的首选形式是这样的: + + p = kmalloc_array(n, sizeof(...), ...); + +分配一个零长数组的首选形式是这样的: + + p = kcalloc(n, sizeof(...), ...); + +两种形式检查分配大小 n * sizeof(...) 的溢出,如果溢出返回 NULL。 + 第十五章:内联弊病 -有一个常见的误解是内联函数是gcc提供的可以让代码运行更快的一个选项。虽然使用内联 +有一个常见的误解是内联函数是 gcc 提供的可以让代码运行更快的一个选项。虽然使用内联 函数有时候是恰当的(比如作为一种替代宏的方式,请看第十二章),不过很多情况下不是 -这样。inline关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核 +这样。inline 关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核 会占用更多的指令高速缓存(译注:一级缓存通常是指令缓存和数据缓存分开的)而且会导 -致pagecache的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址,将 -耗时5毫秒。5毫秒的时间内CPU能执行很多很多指令。 +致 pagecache 的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址, +将耗时 5 毫秒。5 毫秒的时间内 CPU 能执行很多很多指令。 -一个基本的原则是如果一个函数有3行以上,就不要把它变成内联函数。这个原则的一个例 +一个基本的原则是如果一个函数有 3 行以上,就不要把它变成内联函数。这个原则的一个例 外是,如果你知道某个参数是一个编译时常量,而且因为这个常量你确定编译器在编译时能 -优化掉你的函数的大部分代码,那仍然可以给它加上inline关键字。kmalloc()内联函数就 +优化掉你的函数的大部分代码,那仍然可以给它加上 inline 关键字。kmalloc() 内联函数就 是一个很好的例子。 -人们经常主张给static的而且只用了一次的函数加上inline,如此不会有任何损失,因为没 -有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加inline gcc -也可以自动使其内联。而且其他用户可能会要求移除inline,由此而来的争论会抵消inline +人们经常主张给 static 的而且只用了一次的函数加上 inline,如此不会有任何损失,因为没 +有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加 inline gcc +也可以自动使其内联。而且其他用户可能会要求移除 inline,由此而来的争论会抵消 inline 自身的潜在价值,得不偿失。 @@ -613,37 +674,37 @@ vmalloc()。请参考API文档以获取有关它们的详细信息。 的一个值可以表示为一个错误代码整数(-Exxx=失败,0=成功)或者一个“成功”布尔值( 0=失败,非0=成功)。 -混合使用这两种表达方式是难于发现的bug的来源。如果C语言本身严格区分整形和布尔型变 -量,那么编译器就能够帮我们发现这些错误……不过C语言不区分。为了避免产生这种bug,请 +混合使用这两种表达方式是难于发现的 bug 的来源。如果 C 语言本身严格区分整形和布尔型变 +量,那么编译器就能够帮我们发现这些错误……不过 C 语言不区分。为了避免产生这种 bug,请 遵循下面的惯例: 如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代码整 数。如果是一个判断,那么函数应该返回一个“成功”布尔值。 -比如,“add work”是一个命令,所以add_work()函数在成功时返回0,在失败时返回-EBUSY。 -类似的,因为“PCI device present”是一个判断,所以pci_dev_present()函数在成功找到 -一个匹配的设备时应该返回1,如果找不到时应该返回0。 +比如,“add work” 是一个命令,所以 add_work() 函数在成功时返回 0,在失败时返回 -EBUSY。 +类似的,因为 “PCI device present” 是一个判断,所以 pci_dev_present() 函数在成功找到 +一个匹配的设备时应该返回 1,如果找不到时应该返回 0。 所有导出(译注:EXPORT)的函数都必须遵守这个惯例,所有的公共函数也都应该如此。私 有(static)函数不需要如此,但是我们也推荐这样做。 返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。一般的,他们 通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数,他们使用 -NULL或者ERR_PTR机制来报告错误。 +NULL 或者 ERR_PTR 机制来报告错误。 第十七章:不要重新发明内核宏 -头文件include/linux/kernel.h包含了一些宏,你应该使用它们,而不要自己写一些它们的 +头文件 include/linux/kernel.h 包含了一些宏,你应该使用它们,而不要自己写一些它们的 变种。比如,如果你需要计算一个数组的长度,使用这个宏 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 类似的,如果你要计算某结构体成员的大小,使用 - #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) + #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) -还有可以做严格的类型检查的min()和max()宏,如果你需要可以使用它们。你可以自己看看 +还有可以做严格的类型检查的 min() 和 max() 宏,如果你需要可以使用它们。你可以自己看看 那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应在你的代码里 自己重新定义。 @@ -653,42 +714,100 @@ NULL或者ERR_PTR机制来报告错误。 有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs 能够解释被标记成这样的行: --*- mode: c -*- + -*- mode: c -*- 或者这样的: -/* -Local Variables: -compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" -End: -*/ + /* + Local Variables: + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" + End: + */ -Vim能够解释这样的标记: +Vim 能够解释这样的标记: -/* vim:set sw=8 noet */ + /* vim:set sw=8 noet */ 不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不应 该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模 式,或者使用其他可以产生正确的缩进的巧妙方法。 + 第十九章:内联汇编 + +在特定架构的代码中,你也许需要内联汇编来使用 CPU 接口和平台相关功能。在需要 +这么做时,不要犹豫。然而,当 C 可以完成工作时,不要无端地使用内联汇编。如果 +可能,你可以并且应该用 C 和硬件交互。 + +考虑去写通用一点的内联汇编作为简明的辅助函数,而不是重复写下它们的细节。记住 +内联汇编可以使用 C 参数。 + +大而特殊的汇编函数应该放在 .S 文件中,对应 C 的原型定义在 C 头文件中。汇编 +函数的 C 原型应该使用 “asmlinkage”。 + +你可能需要将你的汇编语句标记为 volatile,来阻止 GCC 在没发现任何副作用后就 +移除了它。你不必总是这样做,虽然,这样可以限制不必要的优化。 + +在写一个包含多条指令的单个内联汇编语句时,把每条指令用引号字符串分离,并写在 +单独一行,在每个字符串结尾,除了 \n\t 结尾之外,在汇编输出中适当地缩进下 +一条指令: + + asm ("magic %reg1, #42\n\t" + "more_magic %reg2, %reg3" + : /* outputs */ : /* inputs */ : /* clobbers */); + + + 第二十章:条件编译 + +只要可能,就不要在 .c 文件里面使用预处理条件;这样做让代码更难阅读并且逻辑难以 +跟踪。替代方案是,在头文件定义函数在这些 .c 文件中使用这类的条件表达式,提供空 +操作的桩版本(译注:桩程序,是指用来替换一部分功能的程序段)在 #else 情况下, +再从 .c 文件中无条件地调用这些函数。编译器会避免生成任何桩调用的代码,产生一致 +的结果,但逻辑将更加清晰。 + +宁可编译整个函数,而不是部分函数或部分表达式。而不是在一个表达式添加 ifdef, +解析部分或全部表达式到一个单独的辅助函数,并应用条件到该函数内。 + +如果你有一个在特定配置中可能是未使用的函数或变量,编译器将警告它定义了但未使用, +标记这个定义为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而,如果 +一个函数或变量总是未使用的,就直接删除它。) + +在代码中,可能的情况下,使用 IS_ENABLED 宏来转化某个 Kconfig 标记为 C 的布尔 +表达式,并在正常的 C 条件中使用它: + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +编译器会无条件地做常数合并,就像使用 #ifdef 那样,包含或排除代码块,所以这不会 +带来任何运行时开销。然而,这种方法依旧允许 C 编译器查看块内的代码,并检查它的正确 +性(语法,类型,符号引用,等等)。因此,如果条件不满足,代码块内的引用符号将不存在, +你必须继续使用 #ifdef。 + +在任何有意义的 #if 或 #ifdef 块的末尾(超过几行),在 #endif 同一行的后面写下 +注释,指出该条件表达式被使用。例如: + + #ifdef CONFIG_SOMETHING + ... + #endif /* CONFIG_SOMETHING */ + 附录 I:参考 -The C Programming Language, 第二版, 作者Brian W. Kernighan和Denni -M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (软皮), -0-13-110370-9 (硬皮). URL: http://cm.bell-labs.com/cm/cs/cbook/ +The C Programming Language, 第二版 +作者:Brian W. Kernighan 和 Denni M. Ritchie. +Prentice Hall, Inc., 1988. +ISBN 0-13-110362-8 (软皮), 0-13-110370-9 (硬皮). -The Practice of Programming 作者Brian W. Kernighan和Rob Pike. Addison-Wesley, -Inc., 1999. ISBN 0-201-61586-X. URL: http://cm.bell-labs.com/cm/cs/tpop/ +The Practice of Programming +作者:Brian W. Kernighan 和 Rob Pike. +Addison-Wesley, Inc., 1999. +ISBN 0-201-61586-X. -cpp,gcc,gcc internals和indent的GNU手册——和K&R及本文相符合的部分,全部可以在 -http://www.gnu.org/manual/找到 +GNU 手册 - 遵循 K&R 标准和此文本 - cpp, gcc, gcc internals and indent, +都可以从 http://www.gnu.org/manual/ 找到 WG14是C语言的国际标准化工作组,URL: http://www.open-std.org/JTC1/SC22/WG14/ -Kernel CodingStyle,作者greg@kroah.com发表于OLS 2002: +Kernel CodingStyle,作者 greg@kroah.com 发表于OLS 2002: http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ - --- -最后更新于2007年7月13日。 -- cgit v1.3-14-g43fede From f3e6a55c3653b071705e266473b87696786dfd99 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Fri, 3 Jun 2016 12:03:10 +0200 Subject: Documentation: dmaengine: fix typo for device_resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niklas Söderlund Signed-off-by: Jonathan Corbet --- Documentation/dmaengine/provider.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt index 122b7f4876bb..91ce82d5f0c4 100644 --- a/Documentation/dmaengine/provider.txt +++ b/Documentation/dmaengine/provider.txt @@ -323,7 +323,7 @@ supported. * device_resume - Resumes a transfer on the channel - This command should operate synchronously on the channel, - pausing right away the work of the given channel + resuming right away the work of the given channel * device_terminate_all - Aborts all the pending and ongoing transfers on the channel -- cgit v1.3-14-g43fede From d90368f2fa7ded7c56d214aef087e88bba5199e7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 3 Jun 2016 22:21:35 +0200 Subject: doc/sphinx: Track line-number of starting blocks Design is pretty simple: kernel-doc inserts breadcrumbs with line numbers, and sphinx picks them up. At first I went with a sphinx comment, but inserting those at random places seriously upsets the parser, and must be filtered. Hence why this version now uses "#define LINEO " since one of these ever escape into output it's pretty clear there is a bug. It seems to work well, and at least the 2-3 errors where sphinx complained about something that was not correct in kernel-doc text the line numbers matched up perfectly. v2: Instead of noodling around in the parser state machine, create a ViewList and parse it ourselves. This seems to be the recommended way, per Jani's suggestion. v3: - Split out ViewList pach. Splitting the kernel-doc changes from the sphinx ones isn't possible, since emitting the LINENO lines wreaks havoc with the rst formatting. We must filter them. - Improve the regex per Jani's suggestions, and compile it just once for speed. - Now that LINENO lines are eaten, also add them to function parameter descriptions. Much less content and offset than for in-line struct member descriptions, but still nice to know which exact continuation line upsets sphinx. - Simplify/clarify the line +/-1 business a bit. v4: Split out the scripts/kernel-doc changes and make line-numbers opt-in, as suggested by Jani. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index bd422870101e..4adfb0e91ecc 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -30,6 +30,7 @@ import os import subprocess import sys +import re from docutils import nodes, statemachine from docutils.statemachine import ViewList @@ -50,7 +51,7 @@ class KernelDocDirective(Directive): def run(self): env = self.state.document.settings.env - cmd = [env.config.kerneldoc_bin, '-rst'] + cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] @@ -93,7 +94,19 @@ class KernelDocDirective(Directive): sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) - result = ViewList(lines, source) + result = ViewList() + + lineoffset = 0; + line_regex = re.compile("^#define LINENO ([0-9]+)$") + for line in lines: + match = line_regex.search(line) + if match: + # sphinx counts lines from 0 + lineoffset = int(match.group(1)) - 1 + # we must eat our comments since the upset the markup + else: + result.append(line, source, lineoffset) + lineoffset += 1 node = nodes.section() node.document = self.state.document -- cgit v1.3-14-g43fede From 8c5ad1d6179df31eea1b736c88296db6e3ffd25d Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 4 Jun 2016 21:17:09 +0200 Subject: net: dsa: Document new binding Add the new binding to the documentation of the existing binding. Mark the old binding as deprecated. Signed-off-by: Andrew Lunn Signed-off-by: Florian Fainelli Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dsa/dsa.txt | 278 +++++++++++++++++++++- 1 file changed, 276 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt index 9f4807f90c31..9bbbe7f87d67 100644 --- a/Documentation/devicetree/bindings/net/dsa/dsa.txt +++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt @@ -1,5 +1,279 @@ -Marvell Distributed Switch Architecture Device Tree Bindings ------------------------------------------------------------- +Distributed Switch Architecture Device Tree Bindings +---------------------------------------------------- + +Two bindings exist, one of which has been deprecated due to +limitations. + +Current Binding +--------------- + +Switches are true Linux devices and can be probes by any means. Once +probed, they register to the DSA framework, passing a node +pointer. This node is expected to fulfil the following binding, and +may contain additional properties as required by the device it is +embedded within. + +Required properties: + +- ports : A container for child nodes representing switch ports. + +Optional properties: + +- dsa,member : A two element list indicates which DSA cluster, and position + within the cluster a switch takes. <0 0> is cluster 0, + switch 0. <0 1> is cluster 0, switch 1. <1 0> is cluster 1, + switch 0. A switch not part of any cluster (single device + hanging off a CPU port) must not specify this property + +The ports container has the following properties + +Required properties: + +- #address-cells : Must be 1 +- #size-cells : Must be 0 + +Each port children node must have the following mandatory properties: +- reg : Describes the port address in the switch +- label : Describes the label associated with this port, which + will become the netdev name. Special labels are + "cpu" to indicate a CPU port and "dsa" to + indicate an uplink/downlink port between switches in + the cluster. + +A port labelled "dsa" has the following mandatory property: + +- link : Should be a list of phandles to other switch's DSA + port. This port is used as the outgoing port + towards the phandle ports. The full routing + information must be given, not just the one hop + routes to neighbouring switches. + +A port labelled "cpu" has the following mandatory property: + +- ethernet : Should be a phandle to a valid Ethernet device node. + This host device is what the switch port is + connected to. + +Port child nodes may also contain the following optional standardised +properties, described in binding documents: + +- phy-handle : Phandle to a PHY on an MDIO bus. See + Documentation/devicetree/bindings/net/ethernet.txt + for details. + +- phy-mode : See + Documentation/devicetree/bindings/net/ethernet.txt + for details. + +- fixed-link : Fixed-link subnode describing a link to a non-MDIO + managed entity. See + Documentation/devicetree/bindings/net/fixed-link.txt + for details. + +Example + +The following example shows three switches on three MDIO busses, +linked into one DSA cluster. + +&mdio1 { + #address-cells = <1>; + #size-cells = <0>; + + switch0: switch0@0 { + compatible = "marvell,mv88e6085"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + dsa,member = <0 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + label = "lan0"; + }; + + port@1 { + reg = <1>; + label = "lan1"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + switch0port5: port@5 { + reg = <5>; + label = "dsa"; + phy-mode = "rgmii-txid"; + link = <&switch1port6 + &switch2port9>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&fec1>; + fixed-link { + speed = <100>; + full-duplex; + }; + }; + }; + }; +}; + +&mdio2 { + #address-cells = <1>; + #size-cells = <0>; + + switch1: switch1@0 { + compatible = "marvell,mv88e6085"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + dsa,member = <0 1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + label = "lan3"; + phy-handle = <&switch1phy0>; + }; + + port@1 { + reg = <1>; + label = "lan4"; + phy-handle = <&switch1phy1>; + }; + + port@2 { + reg = <2>; + label = "lan5"; + phy-handle = <&switch1phy2>; + }; + + switch1port5: port@5 { + reg = <5>; + label = "dsa"; + link = <&switch2port9>; + phy-mode = "rgmii-txid"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + switch1port6: port@6 { + reg = <6>; + label = "dsa"; + phy-mode = "rgmii-txid"; + link = <&switch0port5>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + switch1phy0: switch1phy0@0 { + reg = <0>; + }; + switch1phy1: switch1phy0@1 { + reg = <1>; + }; + switch1phy2: switch1phy0@2 { + reg = <2>; + }; + }; + }; +}; + +&mdio4 { + #address-cells = <1>; + #size-cells = <0>; + + switch2: switch2@0 { + compatible = "marvell,mv88e6085"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + dsa,member = <0 2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + label = "lan6"; + }; + + port@1 { + reg = <1>; + label = "lan7"; + }; + + port@2 { + reg = <2>; + label = "lan8"; + }; + + port@3 { + reg = <3>; + label = "optical3"; + fixed-link { + speed = <1000>; + full-duplex; + link-gpios = <&gpio6 2 + GPIO_ACTIVE_HIGH>; + }; + }; + + port@4 { + reg = <4>; + label = "optical4"; + fixed-link { + speed = <1000>; + full-duplex; + link-gpios = <&gpio6 3 + GPIO_ACTIVE_HIGH>; + }; + }; + + switch2port9: port@9 { + reg = <9>; + label = "dsa"; + phy-mode = "rgmii-txid"; + link = <&switch1port5 + &switch0port5>; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +Deprecated Binding +------------------ + +The deprecated binding makes use of a platform device to represent the +switches. The switches themselves are not Linux devices, and make use +of an MDIO bus for management. Required properties: - compatible : Should be "marvell,dsa" -- cgit v1.3-14-g43fede From 2ff1bf77e4d437be502b79443906fcb23e09b81b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 30 May 2016 19:05:09 +0200 Subject: soc: renesas: rcar-sysc: Document r8a7796 support Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Acked-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index b74e4d4785ab..0725fb37a973 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -14,6 +14,7 @@ Required properties: - "renesas,r8a7793-sysc" (R-Car M2-N) - "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7795-sysc" (R-Car H3) + - "renesas,r8a7796-sysc" (R-Car M3-W) - reg: Address start and address range for the device. - #power-domain-cells: Must be 1. -- cgit v1.3-14-g43fede From 24fe2386818682ae7503a2bc210f0baa4d9902ab Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 21 Mar 2016 22:10:25 +0100 Subject: devicetree/bindings: add reset-gpios and vcc-supply for panel-dpi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some displays have a reset input and/or need a regulator to function properly. Allow to specify them for panel-dpi devices. Acked-by: Rob Herring Reviewed-by: Tomi Valkeinen Signed-off-by: Uwe Kleine-König Signed-off-by: Tomi Valkeinen --- Documentation/devicetree/bindings/display/panel/panel-dpi.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/panel/panel-dpi.txt b/Documentation/devicetree/bindings/display/panel/panel-dpi.txt index 216c894d4f99..b52ac52757df 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-dpi.txt +++ b/Documentation/devicetree/bindings/display/panel/panel-dpi.txt @@ -7,6 +7,8 @@ Required properties: Optional properties: - label: a symbolic name for the panel - enable-gpios: panel enable gpio +- reset-gpios: GPIO to control the RESET pin +- vcc-supply: phandle of regulator that will be used to enable power to the display Required nodes: - "panel-timing" containing video timings -- cgit v1.3-14-g43fede From 1faf8692bdc2da1e12c7f2ecda3a9e629ac9b05b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 May 2016 09:37:08 +0200 Subject: clk: renesas: cpg-mssr: Document r8a7796 support Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Tested-by: Simon Horman --- Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index fefb8023020f..394d725ac7e0 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -13,7 +13,8 @@ They provide the following functionalities: Required Properties: - compatible: Must be one of: - - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC + - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) + - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) - reg: Base address and length of the memory resource used by the CPG/MSSR block @@ -21,8 +22,8 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7795) - - "extalr" (r8a7795) + - "extal" (r8a7795, r8a7796) + - "extalr" (r8a7795, r8a7796) - #clock-cells: Must be 2 - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" -- cgit v1.3-14-g43fede From 5c72ae1dbb5348fd465a472a67d170ea5416fe4f Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 15 Apr 2016 15:10:31 +0200 Subject: mtd: nand: sunxi: update DT bindings Document dmas and dma-names properties. Signed-off-by: Boris Brezillon Acked-by: Rob Herring Acked-by: Maxime Ripard Signed-off-by: Boris Brezillon --- Documentation/devicetree/bindings/mtd/sunxi-nand.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt index 086d6f44c4b9..6fdf8f604b39 100644 --- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt @@ -11,6 +11,10 @@ Required properties: * "ahb" : AHB gating clock * "mod" : nand controller clock +Optional properties: +- dmas : shall reference DMA channel associated to the NAND controller. +- dma-names : shall be "rxtx". + Optional children nodes: Children nodes represent the available nand chips. -- cgit v1.3-14-g43fede From ddac4b5a6c08f8800002517ea5352b3eb9451cfc Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 6 Jun 2016 12:21:05 -0300 Subject: Documentation: add fence-array to kernel DocBook Include fence-array files in the DocBook. Signed-off-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465226465-23683-1-git-send-email-gustavo@padovan.org --- Documentation/DocBook/device-drivers.tmpl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index de79efdad46c..5744ec7d2d30 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -132,8 +132,10 @@ X!Edrivers/base/interface.c !Edrivers/dma-buf/dma-buf.c !Edrivers/dma-buf/fence.c !Edrivers/dma-buf/seqno-fence.c +!Edrivers/dma-buf/fence-array.c !Iinclude/linux/fence.h !Iinclude/linux/seqno-fence.h +!Iinclude/linux/fence-array.h !Edrivers/dma-buf/reservation.c !Iinclude/linux/reservation.h !Edrivers/dma-buf/sync_file.c -- cgit v1.3-14-g43fede From 636e2a39cf904946a0e062bc05445149b366ba2e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 3 Jun 2016 18:59:44 +0200 Subject: regulator: axp20x: Add support for the (external) drivebus regulator The axp20x pmics have 2 power inputs, one called ACIN which is intended for to be supplied via a powerbarrel on the board and one called VBUS which is intended to be supplied via an otg connector. In the VBUS case the pmic needs to know if the board is supplying power to the otg connector, because then it should not take any power from its VBUS pin. The axp209 pmic has a N_VBUSEN input pin via which the board can signal to the pmic whether the board is supplying power to the otg connector or not. On the axp221/axp223 this pin can alternatively be used as an output which controls an external regulator which (optionally) supplies power to the otg connector from the board. When the pin is used as output it is called DRIVEVBUS in the datasheet. This commit adds support for the DRIVEVBUS pin as an extra pmic controlled regulator. Since this is optional a new x-powers,drivebus dt property is added. When this is present the misc-control register is written to change the N_VBUSEN input pin to DRIVEVBUS output pin mode and the extra drivebus regulator is registered with the regulator subsystem. Signed-off-by: Hans de Goede Acked-by: Chen-Yu Tsai Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/mfd/axp20x.txt | 6 +++++ drivers/regulator/axp20x-regulator.c | 30 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index d20b1034e967..585a95546288 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt @@ -22,6 +22,11 @@ Optional properties: AXP152/20X: range: 750-1875, Default: 1.5 MHz AXP22X/80X: range: 1800-4050, Default: 3 MHz +- x-powers,drive-vbus-en: axp221 / axp223 only boolean, set this when the + N_VBUSEN pin is used as an output pin to control an external + regulator to drive the OTG VBus, rather then as an input pin + which signals whether the board is driving OTG VBus or not. + - -supply: a phandle to the regulator supply node. May be omitted if inputs are unregulated, such as using the IPSOUT output from the PMIC. @@ -79,6 +84,7 @@ ELDO3 : LDO : eldoin-supply : shared supply LDO_IO0 : LDO : ips-supply : GPIO 0 LDO_IO1 : LDO : ips-supply : GPIO 1 RTC_LDO : LDO : ips-supply : always on +DRIVEVBUS : Enable output : drivevbus-supply : external regulator AXP809 regulators, type, and corresponding input supply names: diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 728be64e817a..6d9ac76a772f 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -36,6 +36,8 @@ #define AXP20X_FREQ_DCDC_MASK 0x0f +#define AXP22X_MISC_N_VBUSEN_FUNC BIT(4) + #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \ _vmask, _ereg, _emask, _enable_val, _disable_val) \ [_family##_##_id] = { \ @@ -230,6 +232,18 @@ static const struct regulator_desc axp22x_regulators[] = { AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000), }; +static const struct regulator_desc axp22x_drivevbus_regulator = { + .name = "drivevbus", + .supply_name = "drivevbus", + .of_match = of_match_ptr("drivevbus"), + .regulators_node = of_match_ptr("regulators"), + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .enable_reg = AXP20X_VBUS_IPSOUT_MGMT, + .enable_mask = BIT(2), + .ops = &axp20x_ops_sw, +}; + static const struct regulator_linear_range axp809_dcdc4_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000), REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000), @@ -411,6 +425,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev) u32 workmode; const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name; const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name; + bool drivevbus = false; switch (axp20x->variant) { case AXP202_ID: @@ -422,6 +437,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev) case AXP223_ID: regulators = axp22x_regulators; nregulators = AXP22X_REG_ID_MAX; + drivevbus = of_property_read_bool(pdev->dev.parent->of_node, + "x-powers,drive-vbus-en"); break; case AXP809_ID: regulators = axp809_regulators; @@ -500,6 +517,19 @@ static int axp20x_regulator_probe(struct platform_device *pdev) &dcdc5_name); } + if (drivevbus) { + /* Change N_VBUSEN sense pin to DRIVEVBUS output pin */ + regmap_update_bits(axp20x->regmap, AXP20X_OVER_TMP, + AXP22X_MISC_N_VBUSEN_FUNC, 0); + rdev = devm_regulator_register(&pdev->dev, + &axp22x_drivevbus_regulator, + &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "Failed to register drivevbus\n"); + return PTR_ERR(rdev); + } + } + return 0; } -- cgit v1.3-14-g43fede From 31bda09d810d6948de31832964160acc002c7afa Mon Sep 17 00:00:00 2001 From: Chris Brand Date: Wed, 11 May 2016 14:36:19 -0700 Subject: Documentation: devicetree: Document BCM23550 bindings Add binding document for Broadcom BCM23550 SoC. BCM23550 has a Cluster Dormant Control IP block that holds cores in an idle state. Introduce a new CPU enable method in which the CDC is accessed to bring the core online. Signed-off-by: Chris Brand Signed-off-by: Florian Fainelli --- .../bindings/arm/bcm/brcm,bcm23550-cpu-method.txt | 36 ++++++++++++++++++++++ .../devicetree/bindings/arm/bcm/brcm,bcm23550.txt | 15 +++++++++ Documentation/devicetree/bindings/arm/cpus.txt | 1 + 3 files changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550-cpu-method.txt create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550-cpu-method.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550-cpu-method.txt new file mode 100644 index 000000000000..a3af54c0e404 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550-cpu-method.txt @@ -0,0 +1,36 @@ +Broadcom Kona Family CPU Enable Method +-------------------------------------- +This binding defines the enable method used for starting secondary +CPUs in the following Broadcom SoCs: + BCM23550 + +The enable method is specified by defining the following required +properties in the "cpu" device tree node: + - enable-method = "brcm,bcm23550"; + - secondary-boot-reg = <...>; + +The secondary-boot-reg property is a u32 value that specifies the +physical address of the register used to request the ROM holding pen +code release a secondary CPU. The value written to the register is +formed by encoding the target CPU id into the low bits of the +physical start address it should jump to. + +Example: + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + enable-method = "brcm,bcm23550"; + secondary-boot-reg = <0x3500417c>; + }; + }; diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550.txt new file mode 100644 index 000000000000..080baad923d6 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550.txt @@ -0,0 +1,15 @@ +Broadcom BCM23550 device tree bindings +-------------------------------------- + +This document describes the device tree bindings for boards with the BCM23550 +SoC. + +Required root node property: + - compatible: brcm,bcm23550 + +Example: + / { + model = "BCM23550 SoC"; + compatible = "brcm,bcm23550"; + [...] + } diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index e97a45681138..ff76088f3b84 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -194,6 +194,7 @@ nodes to be present and contain the properties described below. "allwinner,sun8i-a23" "arm,realview-smp" "brcm,bcm11351-cpu-method" + "brcm,bcm23550" "brcm,bcm-nsp-smp" "brcm,brahma-b15" "marvell,armada-375-smp" -- cgit v1.3-14-g43fede From f72677939cf582118bd645c5015605577db74b25 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 13 May 2016 10:49:12 +0530 Subject: gpio: add DT binding doc for gpio of PMIC max77620/max20024 Maxim Semiconductor's PMIC MAX77620/MAX20024 has 8 GPIO pins which act as GPIO as well as special function mode. Add DT binding document to support these pins in GPIO mode via GPIO framework. Signed-off-by: Laxman Dewangan Acked-by: Rob Herring Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio-max77620.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-max77620.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/gpio-max77620.txt b/Documentation/devicetree/bindings/gpio/gpio-max77620.txt new file mode 100644 index 000000000000..410e716fd3d2 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-max77620.txt @@ -0,0 +1,25 @@ +GPIO driver for MAX77620 Power management IC from Maxim Semiconductor. + +Device has 8 GPIO pins which can be configured as GPIO as well as the +special IO functions. + +Required properties: +------------------- +- gpio-controller : Marks the device node as a gpio controller. +- #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify the gpio polarity: + 0 = active high + 1 = active low +For more details, please refer generic GPIO DT binding document +. + +Example: +-------- +#include +... +max77620@3c { + compatible = "maxim,max77620"; + + gpio-controller; + #gpio-cells = <2>; +}; -- cgit v1.3-14-g43fede From 353661dfe19512fa54c4662d4624dd946a2c8751 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Thu, 19 May 2016 12:17:29 +0530 Subject: gpio: pca953x: Add support for TI PCA9536 TI PCA9536 is 4-Bit I2C GPIO expander without interrupt support[1]. Add support for the same. [1] TRM: http://www.ti.com/lit/ds/symlink/pca9536.pdf Signed-off-by: Vignesh R Acked-by: Rob Herring Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/gpio/gpio-pca953x.txt | 1 + drivers/gpio/gpio-pca953x.c | 1 + 2 files changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt index 6b4a98f74be3..08dd15f89ba9 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt @@ -21,6 +21,7 @@ Required properties: maxim,max7313 maxim,max7315 ti,pca6107 + ti,pca9536 ti,tca6408 ti,tca6416 ti,tca6424 diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5e3be32ebb8d..763028562d22 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -861,6 +861,7 @@ static const struct of_device_id pca953x_dt_ids[] = { { .compatible = "maxim,max7315", .data = OF_953X( 8, PCA_INT), }, { .compatible = "ti,pca6107", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "ti,pca9536", .data = OF_953X( 4, 0), }, { .compatible = "ti,tca6408", .data = OF_953X( 8, PCA_INT), }, { .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), }, { .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), }, -- cgit v1.3-14-g43fede From 23ce62d293b65b7965a5b5a416f897d52eafcee6 Mon Sep 17 00:00:00 2001 From: Andrew-CT Chen Date: Tue, 3 May 2016 07:11:20 -0300 Subject: [media] dt-bindings: Add a binding for Mediatek Video Processor Add a DT binding documentation of Video Processor Unit for the MT8173 SoC from Mediatek. Signed-off-by: Andrew-CT Chen Signed-off-by: Tiffany Lin Acked-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/mediatek-vpu.txt | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/mediatek-vpu.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/mediatek-vpu.txt b/Documentation/devicetree/bindings/media/mediatek-vpu.txt new file mode 100644 index 000000000000..2a5bac37f9a2 --- /dev/null +++ b/Documentation/devicetree/bindings/media/mediatek-vpu.txt @@ -0,0 +1,31 @@ +* Mediatek Video Processor Unit + +Video Processor Unit is a HW video controller. It controls HW Codec including +H.264/VP8/VP9 Decode, H.264/VP8 Encode and Image Processor (scale/rotate/color convert). + +Required properties: + - compatible: "mediatek,mt8173-vpu" + - reg: Must contain an entry for each entry in reg-names. + - reg-names: Must include the following entries: + "tcm": tcm base + "cfg_reg": Main configuration registers base + - interrupts: interrupt number to the cpu. + - clocks : clock name from clock manager + - clock-names: must be main. It is the main clock of VPU + +Optional properties: + - memory-region: phandle to a node describing memory (see + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) + to be used for VPU extended memory; if not present, VPU may be located + anywhere in the memory + +Example: + vpu: vpu@10020000 { + compatible = "mediatek,mt8173-vpu"; + reg = <0 0x10020000 0 0x30000>, + <0 0x10050000 0 0x100>; + reg-names = "tcm", "cfg_reg"; + interrupts = ; + clocks = <&topckgen TOP_SCP_SEL>; + clock-names = "main"; + }; -- cgit v1.3-14-g43fede From 05c1b4480e86a871b18030d6f3d532dc0ecdf38c Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 7 Jun 2016 17:19:04 +0100 Subject: ASoC: sti: Update DT example to match the driver code uniperiph-id, version and mode are ST specific bindings and need the 'st,' prefix. Update the examples, as otherwise copying them yields a runtime error parsing the DT node. Signed-off-by: Peter Griffin Acked-by: Rob Herring Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/st,sti-asoc-card.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt index 4d9a83d9a017..16bcdfb6760e 100644 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt @@ -33,11 +33,11 @@ Required properties: "tx" for "st,sti-uni-player" compatibility "rx" for "st,sti-uni-reader" compatibility - - version: IP version integrated in SOC. + - st,version: IP version integrated in SOC. - dai-name: DAI name that describes the IP. - - IP mode: IP working mode depending on associated codec. + - st,mode: IP working mode depending on associated codec. "HDMI" connected to HDMI codec and support IEC HDMI formats (player only). "SPDIF" connected to SPDIF codec and support SPDIF formats (player only). "PCM" PCM standard mode for I2S or TDM bus. @@ -47,7 +47,7 @@ Required properties ("st,sti-uni-player" compatibility only): - clocks: CPU_DAI IP clock source, listed in the same order than the CPU_DAI properties. - - uniperiph-id: internal SOC IP instance ID. + - st,uniperiph-id: internal SOC IP instance ID. Optional properties: - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for @@ -84,9 +84,9 @@ Example: dmas = <&fdma0 4 0 1>; dai-name = "Uni Player #2 (DAC)"; dma-names = "tx"; - uniperiph-id = <2>; - version = <5>; - mode = "PCM"; + st,uniperiph-id = <2>; + st,version = <5>; + st,mode = "PCM"; }; sti_uni_player3: sti-uni-player@3 { @@ -100,9 +100,9 @@ Example: dmas = <&fdma0 7 0 1>; dma-names = "tx"; dai-name = "Uni Player #3 (SPDIF)"; - uniperiph-id = <3>; - version = <5>; - mode = "SPDIF"; + st,uniperiph-id = <3>; + st,version = <5>; + st,mode = "SPDIF"; }; sti_uni_reader1: sti-uni-reader@1 { @@ -115,7 +115,7 @@ Example: dmas = <&fdma0 6 0 1>; dma-names = "rx"; dai-name = "Uni Reader #1 (HDMI RX)"; - version = <3>; + st,version = <3>; st,mode = "PCM"; }; -- cgit v1.3-14-g43fede From 47d78000eb812643a4c5bd0151af8ee427f89493 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Wed, 25 May 2016 11:29:39 -0500 Subject: Documentation: dt: socfpga: Add interrupt-controller to ecc-manager Designate the ECC Manager as an interrupt controller and add child interrupts. Signed-off-by: Thor Thayer Acked-by: Rob Herring Cc: devicetree@vger.kernel.org Cc: dinguyen@opensource.altera.com Cc: ijc+devicetree@hellion.org.uk Cc: linux-arm-kernel@lists.infradead.org Cc: linux@arm.linux.org.uk Cc: linux-doc@vger.kernel.org Cc: linux-edac Link: http://lkml.kernel.org/r/1464193783-5071-2-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov --- .../devicetree/bindings/arm/altera/socfpga-eccmgr.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt index 5a6b16070a33..15eb0df1d36e 100644 --- a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt +++ b/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt @@ -61,7 +61,9 @@ Required Properties: - #address-cells: must be 1 - #size-cells: must be 1 - interrupts : Should be single bit error interrupt, then double bit error - interrupt. Note the rising edge type. + interrupt. +- interrupt-controller : boolean indicator that ECC Manager is an interrupt controller +- #interrupt-cells : must be set to 2. - ranges : standard definition, should translate from local addresses Subcomponents: @@ -70,11 +72,15 @@ L2 Cache ECC Required Properties: - compatible : Should be "altr,socfpga-a10-l2-ecc" - reg : Address and size for ECC error interrupt clear registers. +- interrupts : Should be single bit error interrupt, then double bit error + interrupt, in this order. On-Chip RAM ECC Required Properties: - compatible : Should be "altr,socfpga-a10-ocram-ecc" - reg : Address and size for ECC block registers. +- interrupts : Should be single bit error interrupt, then double bit error + interrupt, in this order. Example: @@ -85,15 +91,21 @@ Example: #size-cells = <1>; interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>, <0 0 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <2>; ranges; l2-ecc@ffd06010 { compatible = "altr,socfpga-a10-l2-ecc"; reg = <0xffd06010 0x4>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, + <32 IRQ_TYPE_LEVEL_HIGH>; }; ocram-ecc@ff8c3000 { compatible = "altr,socfpga-a10-ocram-ecc"; reg = <0xff8c3000 0x90>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>, + <33 IRQ_TYPE_LEVEL_HIGH> ; }; }; -- cgit v1.3-14-g43fede From 726b4d062e29bacfa686e036f7cd2e3919a20808 Mon Sep 17 00:00:00 2001 From: Raashid Muhammed Date: Fri, 3 Jun 2016 11:45:39 +0530 Subject: ARM: dts: at91: Add DT support for Olimex SAM9-L9260 board. sam9-l9260 is a low cost board designed by Olimex. More information is available at: https://www.olimex.com/Products/ARM/Atmel/SAM9-L9260/ Signed-off-by: Raashid Muhammed Reviewed-by: Vijay Kumar B. Acked-by: Rob Herring Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/arm/olimex.txt | 8 +- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/at91-sam9_l9260.dts | 115 +++++++++++++++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 arch/arm/boot/dts/at91-sam9_l9260.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/olimex.txt b/Documentation/devicetree/bindings/arm/olimex.txt index 007fb5c685a1..d726aeca56be 100644 --- a/Documentation/devicetree/bindings/arm/olimex.txt +++ b/Documentation/devicetree/bindings/arm/olimex.txt @@ -1,5 +1,9 @@ -Olimex i.MX Platforms Device Tree Bindings ------------------------------------------- +Olimex Device Tree Bindings +--------------------------- + +SAM9-L9260 Board +Required root node properties: + - compatible = "olimex,sam9-l9260", "atmel,at91sam9260"; i.MX23 Olinuxino Low Cost Board Required root node properties: diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 06b6c2d695bf..0ee9e6134ee9 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -19,6 +19,7 @@ dtb-$(CONFIG_SOC_SAM_V4_V5) += \ usb_a9260.dtb \ at91sam9261ek.dtb \ at91sam9263ek.dtb \ + at91-sam9_l9260.dtb \ tny_a9263.dtb \ usb_a9263.dtb \ at91-foxg20.dtb \ diff --git a/arch/arm/boot/dts/at91-sam9_l9260.dts b/arch/arm/boot/dts/at91-sam9_l9260.dts new file mode 100644 index 000000000000..349a46189bf1 --- /dev/null +++ b/arch/arm/boot/dts/at91-sam9_l9260.dts @@ -0,0 +1,115 @@ +/* + * at91-sam9_l9260.dts - Device Tree file for Olimex SAM9-L9260 board + * + * Copyright (C) 2016 Raashid Muhammed + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "at91sam9260.dtsi" + +/ { + model = "Olimex sam9-l9260"; + compatible = "olimex,sam9-l9260", "atmel,at91sam9260", "atmel,at91sam9"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0x20000000 0x4000000>; + }; + + clocks { + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <18432000>; + }; + }; + + ahb { + apb { + mmc0: mmc@fffa8000 { + pinctrl-0 = < + &pinctrl_board_mmc0 + &pinctrl_mmc0_clk + &pinctrl_mmc0_slot1_cmd_dat0 + &pinctrl_mmc0_slot1_dat1_3>; + status = "okay"; + + slot@1 { + reg = <1>; + bus-width = <4>; + cd-gpios = <&pioC 8 GPIO_ACTIVE_HIGH>; + wp-gpios = <&pioC 4 GPIO_ACTIVE_HIGH>; + }; + }; + + macb0: ethernet@fffc4000 { + phy-mode = "mii"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ethernet-phy@1 { + reg = <0x1>; + }; + }; + + spi0: spi@fffc8000 { + cs-gpios = <&pioC 11 0>, <0>, <0>, <0>; + status = "okay"; + + flash@0 { + compatible = "atmel,at45", "atmel,dataflash"; + spi-max-frequency = <15000000>; + reg = <0>; + }; + }; + + dbgu: serial@fffff200 { + status = "okay"; + }; + + pinctrl@fffff400 { + mmc0 { + pinctrl_board_mmc0: mmc0-board { + atmel,pins = + ; /* WP pin */ + }; + }; + }; + }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt = <1>; + status = "okay"; + }; + + usb0: ohci@500000 { + status = "okay"; + }; + + }; + + i2c@0 { + status = "okay"; + }; + + leds { + compatible = "gpio-leds"; + + b0 { + label = "b0"; + gpios = <&pioA 6 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + }; +}; -- cgit v1.3-14-g43fede From 3a5e02ced11e22ecd9da3d6710afe15bcfee1d10 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sun, 5 Jun 2016 14:32:23 -0500 Subject: block, drivers: add REQ_OP_FLUSH operation This adds a REQ_OP_FLUSH operation that is sent to request_fn based drivers by the block layer's flush code, instead of sending requests with the request->cmd_flags REQ_FLUSH bit set. Signed-off-by: Mike Christie Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Jens Axboe --- Documentation/block/writeback_cache_control.txt | 6 +++--- arch/um/drivers/ubd_kern.c | 2 +- block/blk-flush.c | 4 ++-- drivers/block/loop.c | 4 ++-- drivers/block/nbd.c | 2 +- drivers/block/osdblk.c | 2 +- drivers/block/ps3disk.c | 4 ++-- drivers/block/skd_main.c | 2 +- drivers/block/virtio_blk.c | 2 +- drivers/block/xen-blkfront.c | 8 ++++---- drivers/ide/ide-disk.c | 2 +- drivers/md/dm.c | 2 +- drivers/mmc/card/block.c | 6 +++--- drivers/mmc/card/queue.h | 3 ++- drivers/mtd/mtd_blkdevs.c | 2 +- drivers/nvme/host/core.c | 2 +- drivers/scsi/sd.c | 7 +++---- include/linux/blk_types.h | 3 ++- include/linux/blkdev.h | 3 +++ kernel/trace/blktrace.c | 5 +++++ 20 files changed, 40 insertions(+), 31 deletions(-) (limited to 'Documentation') diff --git a/Documentation/block/writeback_cache_control.txt b/Documentation/block/writeback_cache_control.txt index 59e0516cbf6b..da70bdacd503 100644 --- a/Documentation/block/writeback_cache_control.txt +++ b/Documentation/block/writeback_cache_control.txt @@ -73,9 +73,9 @@ doing: blk_queue_write_cache(sdkp->disk->queue, true, false); -and handle empty REQ_FLUSH requests in its prep_fn/request_fn. Note that +and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn. Note that REQ_FLUSH requests with a payload are automatically turned into a sequence -of an empty REQ_FLUSH request followed by the actual write by the block +of an empty REQ_OP_FLUSH request followed by the actual write by the block layer. For devices that also support the FUA bit the block layer needs to be told to pass through the REQ_FUA bit using: @@ -83,4 +83,4 @@ to be told to pass through the REQ_FUA bit using: and the driver must handle write requests that have the REQ_FUA bit set in prep_fn/request_fn. If the FUA bit is not natively supported the block -layer turns it into an empty REQ_FLUSH request after the actual write. +layer turns it into an empty REQ_OP_FLUSH request after the actual write. diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 17e96dc29596..ef6b4d960bad 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1286,7 +1286,7 @@ static void do_ubd_request(struct request_queue *q) req = dev->request; - if (req->cmd_flags & REQ_FLUSH) { + if (req_op(req) == REQ_OP_FLUSH) { io_req = kmalloc(sizeof(struct io_thread_req), GFP_ATOMIC); if (io_req == NULL) { diff --git a/block/blk-flush.c b/block/blk-flush.c index 9fd1f63a6348..21f0d5b0d2ca 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -29,7 +29,7 @@ * The actual execution of flush is double buffered. Whenever a request * needs to execute PRE or POSTFLUSH, it queues at * fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a - * flush is issued and the pending_idx is toggled. When the flush + * REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush * completes, all the requests which were pending are proceeded to the next * step. This allows arbitrary merging of different types of FLUSH/FUA * requests. @@ -330,7 +330,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq) } flush_rq->cmd_type = REQ_TYPE_FS; - flush_rq->cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ; + req_set_op_attrs(flush_rq, REQ_OP_FLUSH, WRITE_FLUSH | REQ_FLUSH_SEQ); flush_rq->rq_disk = first_rq->rq_disk; flush_rq->end_io = flush_end_io; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b9b737cafd5f..364d491d4bdd 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -542,7 +542,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; if (op_is_write(req_op(rq))) { - if (rq->cmd_flags & REQ_FLUSH) + if (req_op(rq) == REQ_OP_FLUSH) ret = lo_req_flush(lo, rq); else if (req_op(rq) == REQ_OP_DISCARD) ret = lo_discard(lo, rq, pos); @@ -1659,7 +1659,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx, if (lo->lo_state != Lo_bound) return -EIO; - if (lo->use_dio && (!(cmd->rq->cmd_flags & REQ_FLUSH) || + if (lo->use_dio && (req_op(cmd->rq) != REQ_OP_FLUSH || req_op(cmd->rq) == REQ_OP_DISCARD)) cmd->use_aio = true; else diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 6c2c28d124d0..d6f3c9336f29 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -284,7 +284,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req) type = NBD_CMD_DISC; else if (req_op(req) == REQ_OP_DISCARD) type = NBD_CMD_TRIM; - else if (req->cmd_flags & REQ_FLUSH) + else if (req_op(req) == REQ_OP_FLUSH) type = NBD_CMD_FLUSH; else if (rq_data_dir(req) == WRITE) type = NBD_CMD_WRITE; diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index c2854a2bfdb0..92900f5f0b47 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c @@ -321,7 +321,7 @@ static void osdblk_rq_fn(struct request_queue *q) * driver-specific, etc. */ - do_flush = rq->cmd_flags & REQ_FLUSH; + do_flush = (req_op(rq) == REQ_OP_FLUSH); do_write = (rq_data_dir(rq) == WRITE); if (!do_flush) { /* osd_flush does not use a bio */ diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 4b7e405830d7..acb44529c05e 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -196,7 +196,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev, dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); while ((req = blk_fetch_request(q))) { - if (req->cmd_flags & REQ_FLUSH) { + if (req_op(req) == REQ_OP_FLUSH) { if (ps3disk_submit_flush_request(dev, req)) break; } else if (req->cmd_type == REQ_TYPE_FS) { @@ -256,7 +256,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) return IRQ_HANDLED; } - if (req->cmd_flags & REQ_FLUSH) { + if (req_op(req) == REQ_OP_FLUSH) { read = 0; op = "flush"; } else { diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index 910e065918af..5c07a23e2ada 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c @@ -597,7 +597,7 @@ static void skd_request_fn(struct request_queue *q) data_dir = rq_data_dir(req); io_flags = req->cmd_flags; - if (io_flags & REQ_FLUSH) + if (req_op(req) == REQ_OP_FLUSH) flush++; if (io_flags & REQ_FUA) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 42758b52768c..18e4069dd24b 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -172,7 +172,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); vbr->req = req; - if (req->cmd_flags & REQ_FLUSH) { + if (req_op(req) == REQ_OP_FLUSH) { vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_FLUSH); vbr->out_hdr.sector = 0; vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req)); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 6fd160197b7a..3aeb25bd5057 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -743,7 +743,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri * The indirect operation can only be a BLKIF_OP_READ or * BLKIF_OP_WRITE */ - BUG_ON(req->cmd_flags & (REQ_FLUSH | REQ_FUA)); + BUG_ON(req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA); ring_req->operation = BLKIF_OP_INDIRECT; ring_req->u.indirect.indirect_op = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; @@ -755,7 +755,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri ring_req->u.rw.handle = info->handle; ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; - if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) { + if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) { /* * Ideally we can do an unordered flush-to-disk. * In case the backend onlysupports barriers, use that. @@ -865,7 +865,7 @@ static inline bool blkif_request_flush_invalid(struct request *req, struct blkfront_info *info) { return ((req->cmd_type != REQ_TYPE_FS) || - ((req->cmd_flags & REQ_FLUSH) && + ((req_op(req) == REQ_OP_FLUSH) && !(info->feature_flush & REQ_FLUSH)) || ((req->cmd_flags & REQ_FUA) && !(info->feature_flush & REQ_FUA))); @@ -2055,7 +2055,7 @@ static int blkif_recover(struct blkfront_info *info) /* * Get the bios in the request so we can re-queue them. */ - if (copy[i].request->cmd_flags & REQ_FLUSH || + if (req_op(copy[i].request) == REQ_OP_FLUSH || req_op(copy[i].request) == REQ_OP_DISCARD || copy[i].request->cmd_flags & (REQ_FUA | REQ_SECURE)) { /* diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 05dbcce70b0e..e378ef70ed63 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -431,7 +431,7 @@ static int idedisk_prep_fn(struct request_queue *q, struct request *rq) ide_drive_t *drive = q->queuedata; struct ide_cmd *cmd; - if (!(rq->cmd_flags & REQ_FLUSH)) + if (req_op(rq) != REQ_OP_FLUSH) return BLKPREP_OK; if (rq->special) { diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f6b104c77b6d..fcc68c8edba0 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2171,7 +2171,7 @@ static void dm_request_fn(struct request_queue *q) /* always use block 0 to find the target for flushes for now */ pos = 0; - if (!(rq->cmd_flags & REQ_FLUSH)) + if (req_op(rq) != REQ_OP_FLUSH) pos = blk_rq_pos(rq); if ((dm_request_peeked_before_merge_deadline(md) && diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 201a8719f6c4..bca20f88a8b2 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1722,7 +1722,8 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) !IS_ALIGNED(blk_rq_sectors(next), 8)) break; - if (req_op(next) == REQ_OP_DISCARD || next->cmd_flags & REQ_FLUSH) + if (req_op(next) == REQ_OP_DISCARD || + req_op(next) == REQ_OP_FLUSH) break; if (rq_data_dir(cur) != rq_data_dir(next)) @@ -2147,7 +2148,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_card *card = md->queue.card; struct mmc_host *host = card->host; unsigned long flags; - unsigned int cmd_flags = req ? req->cmd_flags : 0; if (req && !mq->mqrq_prev->req) /* claim host only for the first request */ @@ -2171,7 +2171,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ret = mmc_blk_issue_secdiscard_rq(mq, req); else ret = mmc_blk_issue_discard_rq(mq, req); - } else if (cmd_flags & REQ_FLUSH) { + } else if (req && req_op(req) == REQ_OP_FLUSH) { /* complete ongoing async transfer before issuing flush */ if (card->host->areq) mmc_blk_issue_rw_rq(mq, NULL); diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 9fb26f20a44d..d62531124d54 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -3,7 +3,8 @@ static inline bool mmc_req_is_special(struct request *req) { - return req && (req->cmd_flags & REQ_FLUSH || req_op(req) == REQ_OP_DISCARD); + return req && + (req_op(req) == REQ_OP_FLUSH || req_op(req) == REQ_OP_DISCARD); } struct request; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 4eb9a5fb151c..78b3eb45faf6 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -87,7 +87,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, if (req->cmd_type != REQ_TYPE_FS) return -EIO; - if (req->cmd_flags & REQ_FLUSH) + if (req_op(req) == REQ_OP_FLUSH) return tr->flush(dev); if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 089b8b8aad4f..abdfdcfb66f4 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -290,7 +290,7 @@ int nvme_setup_cmd(struct nvme_ns *ns, struct request *req, if (req->cmd_type == REQ_TYPE_DRV_PRIV) memcpy(cmd, req->cmd, sizeof(*cmd)); - else if (req->cmd_flags & REQ_FLUSH) + else if (req_op(req) == REQ_OP_FLUSH) nvme_setup_flush(ns, cmd); else if (req_op(req) == REQ_OP_DISCARD) ret = nvme_setup_discard(ns, req, cmd); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fad86ad89e64..5a9db0fe1ee0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1143,12 +1143,11 @@ static int sd_init_command(struct scsi_cmnd *cmd) return sd_setup_discard_cmnd(cmd); case REQ_OP_WRITE_SAME: return sd_setup_write_same_cmnd(cmd); + case REQ_OP_FLUSH: + return sd_setup_flush_cmnd(cmd); case REQ_OP_READ: case REQ_OP_WRITE: - if (rq->cmd_flags & REQ_FLUSH) - return sd_setup_flush_cmnd(cmd); - else - return sd_setup_read_write_cmnd(cmd); + return sd_setup_read_write_cmnd(cmd); default: BUG(); } diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 23c1ab2a9475..32d87522f349 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -249,9 +249,10 @@ enum req_op { REQ_OP_WRITE, REQ_OP_DISCARD, /* request to discard sectors */ REQ_OP_WRITE_SAME, /* write same block many times */ + REQ_OP_FLUSH, /* request for cache flush */ }; -#define REQ_OP_BITS 2 +#define REQ_OP_BITS 3 typedef unsigned int blk_qc_t; #define BLK_QC_T_NONE -1U diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 78ae3dbf2de1..0c9f8793c87e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -666,6 +666,9 @@ static inline bool rq_mergeable(struct request *rq) if (rq->cmd_type != REQ_TYPE_FS) return false; + if (req_op(rq) == REQ_OP_FLUSH) + return false; + if (rq->cmd_flags & REQ_NOMERGE_FLAGS) return false; diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 2d16fad519b2..0c70fbb6ea8d 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -223,6 +223,8 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= MASK_TC_BIT(op_flags, FUA); if (op == REQ_OP_DISCARD) what |= BLK_TC_ACT(BLK_TC_DISCARD); + if (op == REQ_OP_FLUSH) + what |= BLK_TC_ACT(BLK_TC_FLUSH); pid = tsk->pid; if (act_log_check(bt, what, sector, pid)) @@ -1788,6 +1790,9 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes) case REQ_OP_DISCARD: rwbs[i++] = 'D'; break; + case REQ_OP_FLUSH: + rwbs[i++] = 'F'; + break; case REQ_OP_READ: rwbs[i++] = 'R'; break; -- cgit v1.3-14-g43fede From 28a8f0d317bf225ff15008f5dd66ae16242dd843 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sun, 5 Jun 2016 14:32:25 -0500 Subject: block, drivers, fs: rename REQ_FLUSH to REQ_PREFLUSH To avoid confusion between REQ_OP_FLUSH, which is handled by request_fn drivers, and upper layers requesting the block layer perform a flush sequence along with possibly a WRITE, this patch renames REQ_FLUSH to REQ_PREFLUSH. Signed-off-by: Mike Christie Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Jens Axboe --- Documentation/block/writeback_cache_control.txt | 22 +++++++++++----------- Documentation/device-mapper/log-writes.txt | 10 +++++----- block/blk-core.c | 12 ++++++------ block/blk-flush.c | 16 ++++++++-------- block/blk-mq.c | 4 ++-- drivers/block/drbd/drbd_actlog.c | 4 ++-- drivers/block/drbd/drbd_main.c | 2 +- drivers/block/drbd/drbd_protocol.h | 2 +- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/drbd/drbd_req.c | 2 +- drivers/md/bcache/journal.c | 2 +- drivers/md/bcache/request.c | 8 ++++---- drivers/md/dm-cache-target.c | 12 ++++++------ drivers/md/dm-crypt.c | 7 ++++--- drivers/md/dm-era-target.c | 4 ++-- drivers/md/dm-io.c | 2 +- drivers/md/dm-log-writes.c | 2 +- drivers/md/dm-raid1.c | 5 +++-- drivers/md/dm-region-hash.c | 4 ++-- drivers/md/dm-snap.c | 6 +++--- drivers/md/dm-stripe.c | 2 +- drivers/md/dm-thin.c | 8 ++++---- drivers/md/dm.c | 12 ++++++------ drivers/md/linear.c | 2 +- drivers/md/md.c | 2 +- drivers/md/md.h | 2 +- drivers/md/multipath.c | 2 +- drivers/md/raid0.c | 2 +- drivers/md/raid1.c | 3 ++- drivers/md/raid10.c | 2 +- drivers/md/raid5-cache.c | 2 +- drivers/md/raid5.c | 2 +- fs/btrfs/check-integrity.c | 8 ++++---- fs/jbd2/journal.c | 2 +- fs/xfs/xfs_buf.c | 2 +- include/linux/blk_types.h | 8 ++++---- include/linux/fs.h | 4 ++-- include/trace/events/f2fs.h | 2 +- kernel/trace/blktrace.c | 5 +++-- 39 files changed, 102 insertions(+), 98 deletions(-) (limited to 'Documentation') diff --git a/Documentation/block/writeback_cache_control.txt b/Documentation/block/writeback_cache_control.txt index da70bdacd503..8a6bdada5f6b 100644 --- a/Documentation/block/writeback_cache_control.txt +++ b/Documentation/block/writeback_cache_control.txt @@ -20,11 +20,11 @@ a forced cache flush, and the Force Unit Access (FUA) flag for requests. Explicit cache flushes ---------------------- -The REQ_FLUSH flag can be OR ed into the r/w flags of a bio submitted from +The REQ_PREFLUSH flag can be OR ed into the r/w flags of a bio submitted from the filesystem and will make sure the volatile cache of the storage device has been flushed before the actual I/O operation is started. This explicitly guarantees that previously completed write requests are on non-volatile -storage before the flagged bio starts. In addition the REQ_FLUSH flag can be +storage before the flagged bio starts. In addition the REQ_PREFLUSH flag can be set on an otherwise empty bio structure, which causes only an explicit cache flush without any dependent I/O. It is recommend to use the blkdev_issue_flush() helper for a pure cache flush. @@ -41,21 +41,21 @@ signaled after the data has been committed to non-volatile storage. Implementation details for filesystems -------------------------------------- -Filesystems can simply set the REQ_FLUSH and REQ_FUA bits and do not have to +Filesystems can simply set the REQ_PREFLUSH and REQ_FUA bits and do not have to worry if the underlying devices need any explicit cache flushing and how -the Forced Unit Access is implemented. The REQ_FLUSH and REQ_FUA flags +the Forced Unit Access is implemented. The REQ_PREFLUSH and REQ_FUA flags may both be set on a single bio. Implementation details for make_request_fn based block drivers -------------------------------------------------------------- -These drivers will always see the REQ_FLUSH and REQ_FUA bits as they sit +These drivers will always see the REQ_PREFLUSH and REQ_FUA bits as they sit directly below the submit_bio interface. For remapping drivers the REQ_FUA bits need to be propagated to underlying devices, and a global flush needs -to be implemented for bios with the REQ_FLUSH bit set. For real device -drivers that do not have a volatile cache the REQ_FLUSH and REQ_FUA bits -on non-empty bios can simply be ignored, and REQ_FLUSH requests without +to be implemented for bios with the REQ_PREFLUSH bit set. For real device +drivers that do not have a volatile cache the REQ_PREFLUSH and REQ_FUA bits +on non-empty bios can simply be ignored, and REQ_PREFLUSH requests without data can be completed successfully without doing any work. Drivers for devices with volatile caches need to implement the support for these flags themselves without any help from the block layer. @@ -65,8 +65,8 @@ Implementation details for request_fn based block drivers -------------------------------------------------------------- For devices that do not support volatile write caches there is no driver -support required, the block layer completes empty REQ_FLUSH requests before -entering the driver and strips off the REQ_FLUSH and REQ_FUA bits from +support required, the block layer completes empty REQ_PREFLUSH requests before +entering the driver and strips off the REQ_PREFLUSH and REQ_FUA bits from requests that have a payload. For devices with volatile write caches the driver needs to tell the block layer that it supports flushing caches by doing: @@ -74,7 +74,7 @@ doing: blk_queue_write_cache(sdkp->disk->queue, true, false); and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn. Note that -REQ_FLUSH requests with a payload are automatically turned into a sequence +REQ_PREFLUSH requests with a payload are automatically turned into a sequence of an empty REQ_OP_FLUSH request followed by the actual write by the block layer. For devices that also support the FUA bit the block layer needs to be told to pass through the REQ_FUA bit using: diff --git a/Documentation/device-mapper/log-writes.txt b/Documentation/device-mapper/log-writes.txt index c10f30c9b534..f4ebcbaf50f3 100644 --- a/Documentation/device-mapper/log-writes.txt +++ b/Documentation/device-mapper/log-writes.txt @@ -14,14 +14,14 @@ Log Ordering We log things in order of completion once we are sure the write is no longer in cache. This means that normal WRITE requests are not actually logged until the -next REQ_FLUSH request. This is to make it easier for userspace to replay the -log in a way that correlates to what is on disk and not what is in cache, to -make it easier to detect improper waiting/flushing. +next REQ_PREFLUSH request. This is to make it easier for userspace to replay +the log in a way that correlates to what is on disk and not what is in cache, +to make it easier to detect improper waiting/flushing. This works by attaching all WRITE requests to a list once the write completes. -Once we see a REQ_FLUSH request we splice this list onto the request and once +Once we see a REQ_PREFLUSH request we splice this list onto the request and once the FLUSH request completes we log all of the WRITEs and then the FLUSH. Only -completed WRITEs, at the time the REQ_FLUSH is issued, are added in order to +completed WRITEs, at the time the REQ_PREFLUSH is issued, are added in order to simulate the worst case scenario with regard to power failures. Consider the following example (W means write, C means complete): diff --git a/block/blk-core.c b/block/blk-core.c index c7d66c23a708..32a283eb7274 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1029,7 +1029,7 @@ static bool blk_rq_should_init_elevator(struct bio *bio) * Flush requests do not use the elevator so skip initialization. * This allows a request to share the flush and elevator data. */ - if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) + if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) return false; return true; @@ -1736,7 +1736,7 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio) return BLK_QC_T_NONE; } - if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) { + if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) { spin_lock_irq(q->queue_lock); where = ELEVATOR_INSERT_FLUSH; goto get_rq; @@ -1968,9 +1968,9 @@ generic_make_request_checks(struct bio *bio) * drivers without flush support don't have to worry * about them. */ - if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) && + if ((bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) && !test_bit(QUEUE_FLAG_WC, &q->queue_flags)) { - bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA); + bio->bi_rw &= ~(REQ_PREFLUSH | REQ_FUA); if (!nr_sectors) { err = 0; goto end_io; @@ -2217,7 +2217,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq) */ BUG_ON(blk_queued_rq(rq)); - if (rq->cmd_flags & (REQ_FLUSH|REQ_FUA)) + if (rq->cmd_flags & (REQ_PREFLUSH | REQ_FUA)) where = ELEVATOR_INSERT_FLUSH; add_acct_request(q, rq, where); @@ -3311,7 +3311,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) /* * rq is already accounted, so use raw insert */ - if (rq->cmd_flags & (REQ_FLUSH | REQ_FUA)) + if (rq->cmd_flags & (REQ_PREFLUSH | REQ_FUA)) __elv_add_request(q, rq, ELEVATOR_INSERT_FLUSH); else __elv_add_request(q, rq, ELEVATOR_INSERT_SORT_MERGE); diff --git a/block/blk-flush.c b/block/blk-flush.c index 21f0d5b0d2ca..d308def812db 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -10,8 +10,8 @@ * optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request * properties and hardware capability. * - * If a request doesn't have data, only REQ_FLUSH makes sense, which - * indicates a simple flush request. If there is data, REQ_FLUSH indicates + * If a request doesn't have data, only REQ_PREFLUSH makes sense, which + * indicates a simple flush request. If there is data, REQ_PREFLUSH indicates * that the device cache should be flushed before the data is executed, and * REQ_FUA means that the data must be on non-volatile media on request * completion. @@ -20,11 +20,11 @@ * difference. The requests are either completed immediately if there's no * data or executed as normal requests otherwise. * - * If the device has writeback cache and supports FUA, REQ_FLUSH is + * If the device has writeback cache and supports FUA, REQ_PREFLUSH is * translated to PREFLUSH but REQ_FUA is passed down directly with DATA. * - * If the device has writeback cache and doesn't support FUA, REQ_FLUSH is - * translated to PREFLUSH and REQ_FUA to POSTFLUSH. + * If the device has writeback cache and doesn't support FUA, REQ_PREFLUSH + * is translated to PREFLUSH and REQ_FUA to POSTFLUSH. * * The actual execution of flush is double buffered. Whenever a request * needs to execute PRE or POSTFLUSH, it queues at @@ -103,7 +103,7 @@ static unsigned int blk_flush_policy(unsigned long fflags, struct request *rq) policy |= REQ_FSEQ_DATA; if (fflags & (1UL << QUEUE_FLAG_WC)) { - if (rq->cmd_flags & REQ_FLUSH) + if (rq->cmd_flags & REQ_PREFLUSH) policy |= REQ_FSEQ_PREFLUSH; if (!(fflags & (1UL << QUEUE_FLAG_FUA)) && (rq->cmd_flags & REQ_FUA)) @@ -391,9 +391,9 @@ void blk_insert_flush(struct request *rq) /* * @policy now records what operations need to be done. Adjust - * REQ_FLUSH and FUA for the driver. + * REQ_PREFLUSH and FUA for the driver. */ - rq->cmd_flags &= ~REQ_FLUSH; + rq->cmd_flags &= ~REQ_PREFLUSH; if (!(fflags & (1UL << QUEUE_FLAG_FUA))) rq->cmd_flags &= ~REQ_FUA; diff --git a/block/blk-mq.c b/block/blk-mq.c index 29bcd9c07a34..13f460368759 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1247,7 +1247,7 @@ static int blk_mq_direct_issue_request(struct request *rq, blk_qc_t *cookie) static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) { const int is_sync = rw_is_sync(bio_op(bio), bio->bi_rw); - const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA); + const int is_flush_fua = bio->bi_rw & (REQ_PREFLUSH | REQ_FUA); struct blk_map_ctx data; struct request *rq; unsigned int request_count = 0; @@ -1344,7 +1344,7 @@ done: static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio) { const int is_sync = rw_is_sync(bio_op(bio), bio->bi_rw); - const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA); + const int is_flush_fua = bio->bi_rw & (REQ_PREFLUSH | REQ_FUA); struct blk_plug *plug; unsigned int request_count = 0; struct blk_map_ctx data; diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index f236a31cc095..d524973f94b3 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -148,7 +148,7 @@ static int _drbd_md_sync_page_io(struct drbd_device *device, device->md_io.error = -ENODEV; if ((op == REQ_OP_WRITE) && !test_bit(MD_NO_FUA, &device->flags)) - op_flags |= REQ_FUA | REQ_FLUSH; + op_flags |= REQ_FUA | REQ_PREFLUSH; op_flags |= REQ_SYNC | REQ_NOIDLE; bio = bio_alloc_drbd(GFP_NOIO); @@ -847,7 +847,7 @@ int __drbd_change_sync(struct drbd_device *device, sector_t sector, int size, unsigned long count = 0; sector_t esector, nr_sectors; - /* This would be an empty REQ_FLUSH, be silent. */ + /* This would be an empty REQ_PREFLUSH, be silent. */ if ((mode == SET_OUT_OF_SYNC) && size == 0) return 0; diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index d55febcaa414..2b37744db0fa 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1609,7 +1609,7 @@ static u32 bio_flags_to_wire(struct drbd_connection *connection, if (connection->agreed_pro_version >= 95) return (bio->bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) | (bio->bi_rw & REQ_FUA ? DP_FUA : 0) | - (bio->bi_rw & REQ_FLUSH ? DP_FLUSH : 0) | + (bio->bi_rw & REQ_PREFLUSH ? DP_FLUSH : 0) | (bio_op(bio) == REQ_OP_DISCARD ? DP_DISCARD : 0); else return bio->bi_rw & REQ_SYNC ? DP_RW_SYNC : 0; diff --git a/drivers/block/drbd/drbd_protocol.h b/drivers/block/drbd/drbd_protocol.h index ef9245363dcc..129f8c76c9b1 100644 --- a/drivers/block/drbd/drbd_protocol.h +++ b/drivers/block/drbd/drbd_protocol.h @@ -112,7 +112,7 @@ struct p_header100 { #define DP_MAY_SET_IN_SYNC 4 #define DP_UNPLUG 8 /* not used anymore */ #define DP_FUA 16 /* equals REQ_FUA */ -#define DP_FLUSH 32 /* equals REQ_FLUSH */ +#define DP_FLUSH 32 /* equals REQ_PREFLUSH */ #define DP_DISCARD 64 /* equals REQ_DISCARD */ #define DP_SEND_RECEIVE_ACK 128 /* This is a proto B write request */ #define DP_SEND_WRITE_ACK 256 /* This is a proto C write request */ diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 6c5997894475..1ee002352ea2 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2158,7 +2158,7 @@ static unsigned long wire_flags_to_bio_flags(u32 dpf) { return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) | (dpf & DP_FUA ? REQ_FUA : 0) | - (dpf & DP_FLUSH ? REQ_FLUSH : 0); + (dpf & DP_FLUSH ? REQ_PREFLUSH : 0); } static unsigned long wire_flags_to_bio_op(u32 dpf) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 2255dcfebd2b..eef6e9575b4e 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1132,7 +1132,7 @@ static int drbd_process_write_request(struct drbd_request *req) * replicating, in which case there is no point. */ if (unlikely(req->i.size == 0)) { /* The only size==0 bios we expect are empty flushes. */ - D_ASSERT(device, req->master_bio->bi_rw & REQ_FLUSH); + D_ASSERT(device, req->master_bio->bi_rw & REQ_PREFLUSH); if (remote) _req_mod(req, QUEUE_AS_DRBD_BARRIER); return remote; diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index a3c3b309ff4a..6925023e12d4 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -631,7 +631,7 @@ static void journal_write_unlocked(struct closure *cl) bio->bi_end_io = journal_write_endio; bio->bi_private = w; bio_set_op_attrs(bio, REQ_OP_WRITE, - REQ_SYNC|REQ_META|REQ_FLUSH|REQ_FUA); + REQ_SYNC|REQ_META|REQ_PREFLUSH|REQ_FUA); bch_bio_map(bio, w->data); trace_bcache_journal_write(bio); diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 016b0aa7199c..69f16f43f8ab 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -205,10 +205,10 @@ static void bch_data_insert_start(struct closure *cl) return bch_data_invalidate(cl); /* - * Journal writes are marked REQ_FLUSH; if the original write was a + * Journal writes are marked REQ_PREFLUSH; if the original write was a * flush, it'll wait on the journal write. */ - bio->bi_rw &= ~(REQ_FLUSH|REQ_FUA); + bio->bi_rw &= ~(REQ_PREFLUSH|REQ_FUA); do { unsigned i; @@ -668,7 +668,7 @@ static inline struct search *search_alloc(struct bio *bio, s->iop.write_prio = 0; s->iop.error = 0; s->iop.flags = 0; - s->iop.flush_journal = (bio->bi_rw & (REQ_FLUSH|REQ_FUA)) != 0; + s->iop.flush_journal = (bio->bi_rw & (REQ_PREFLUSH|REQ_FUA)) != 0; s->iop.wq = bcache_wq; return s; @@ -920,7 +920,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s) bch_writeback_add(dc); s->iop.bio = bio; - if (bio->bi_rw & REQ_FLUSH) { + if (bio->bi_rw & REQ_PREFLUSH) { /* Also need to send a flush to the backing device */ struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0, dc->disk.bio_split); diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 540e80eb317d..718744db62df 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -788,7 +788,7 @@ static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio) spin_lock_irqsave(&cache->lock, flags); if (cache->need_tick_bio && - !(bio->bi_rw & (REQ_FUA | REQ_FLUSH)) && + !(bio->bi_rw & (REQ_FUA | REQ_PREFLUSH)) && bio_op(bio) != REQ_OP_DISCARD) { pb->tick = true; cache->need_tick_bio = false; @@ -830,7 +830,7 @@ static dm_oblock_t get_bio_block(struct cache *cache, struct bio *bio) static int bio_triggers_commit(struct cache *cache, struct bio *bio) { - return bio->bi_rw & (REQ_FLUSH | REQ_FUA); + return bio->bi_rw & (REQ_PREFLUSH | REQ_FUA); } /* @@ -1069,7 +1069,7 @@ static void dec_io_migrations(struct cache *cache) static bool discard_or_flush(struct bio *bio) { return bio_op(bio) == REQ_OP_DISCARD || - bio->bi_rw & (REQ_FLUSH | REQ_FUA); + bio->bi_rw & (REQ_PREFLUSH | REQ_FUA); } static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell) @@ -1614,8 +1614,8 @@ static void process_flush_bio(struct cache *cache, struct bio *bio) remap_to_cache(cache, bio, 0); /* - * REQ_FLUSH is not directed at any particular block so we don't - * need to inc_ds(). REQ_FUA's are split into a write + REQ_FLUSH + * REQ_PREFLUSH is not directed at any particular block so we don't + * need to inc_ds(). REQ_FUA's are split into a write + REQ_PREFLUSH * by dm-core. */ issue(cache, bio); @@ -1980,7 +1980,7 @@ static void process_deferred_bios(struct cache *cache) bio = bio_list_pop(&bios); - if (bio->bi_rw & REQ_FLUSH) + if (bio->bi_rw & REQ_PREFLUSH) process_flush_bio(cache, bio); else if (bio_op(bio) == REQ_OP_DISCARD) process_discard_bio(cache, &structs, bio); diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 057d19b5e196..96dd5d7e454a 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1911,11 +1911,12 @@ static int crypt_map(struct dm_target *ti, struct bio *bio) struct crypt_config *cc = ti->private; /* - * If bio is REQ_FLUSH or REQ_OP_DISCARD, just bypass crypt queues. - * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight + * If bio is REQ_PREFLUSH or REQ_OP_DISCARD, just bypass crypt queues. + * - for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight * - for REQ_OP_DISCARD caller must use flush if IO ordering matters */ - if (unlikely(bio->bi_rw & REQ_FLUSH || bio_op(bio) == REQ_OP_DISCARD)) { + if (unlikely(bio->bi_rw & REQ_PREFLUSH || + bio_op(bio) == REQ_OP_DISCARD)) { bio->bi_bdev = cc->dev->bdev; if (bio_sectors(bio)) bio->bi_iter.bi_sector = cc->start + diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c index 665bf3285618..2faf49d8f4d7 100644 --- a/drivers/md/dm-era-target.c +++ b/drivers/md/dm-era-target.c @@ -1540,9 +1540,9 @@ static int era_map(struct dm_target *ti, struct bio *bio) remap_to_origin(era, bio); /* - * REQ_FLUSH bios carry no data, so we're not interested in them. + * REQ_PREFLUSH bios carry no data, so we're not interested in them. */ - if (!(bio->bi_rw & REQ_FLUSH) && + if (!(bio->bi_rw & REQ_PREFLUSH) && (bio_data_dir(bio) == WRITE) && !metadata_current_marked(era->md, block)) { defer_bio(era, bio); diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 22e0597d631e..0e225fd4a8d1 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -380,7 +380,7 @@ static void dispatch_io(int op, int op_flags, unsigned int num_regions, */ for (i = 0; i < num_regions; i++) { *dp = old_pages; - if (where[i].count || (op_flags & REQ_FLUSH)) + if (where[i].count || (op_flags & REQ_PREFLUSH)) do_region(op, op_flags, i, where + i, dp, io); } diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c index 0edb8ea51e46..b5dbf7a0515e 100644 --- a/drivers/md/dm-log-writes.c +++ b/drivers/md/dm-log-writes.c @@ -555,7 +555,7 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio) struct bio_vec bv; size_t alloc_size; int i = 0; - bool flush_bio = (bio->bi_rw & REQ_FLUSH); + bool flush_bio = (bio->bi_rw & REQ_PREFLUSH); bool fua_bio = (bio->bi_rw & REQ_FUA); bool discard_bio = (bio_op(bio) == REQ_OP_DISCARD); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 907df2ba8fd4..9f5f460c0e92 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -704,7 +704,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) bio_list_init(&requeue); while ((bio = bio_list_pop(writes))) { - if ((bio->bi_rw & REQ_FLUSH) || + if ((bio->bi_rw & REQ_PREFLUSH) || (bio_op(bio) == REQ_OP_DISCARD)) { bio_list_add(&sync, bio); continue; @@ -1253,7 +1253,8 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) * We need to dec pending if this was a write. */ if (rw == WRITE) { - if (!(bio->bi_rw & REQ_FLUSH) && bio_op(bio) != REQ_OP_DISCARD) + if (!(bio->bi_rw & REQ_PREFLUSH) && + bio_op(bio) != REQ_OP_DISCARD) dm_rh_dec(ms->rh, bio_record->write_region); return error; } diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 3550ca7c6577..b11813431f31 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -398,7 +398,7 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) region_t region = dm_rh_bio_to_region(rh, bio); int recovering = 0; - if (bio->bi_rw & REQ_FLUSH) { + if (bio->bi_rw & REQ_PREFLUSH) { rh->flush_failure = 1; return; } @@ -526,7 +526,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) struct bio *bio; for (bio = bios->head; bio; bio = bio->bi_next) { - if (bio->bi_rw & REQ_FLUSH || bio_op(bio) == REQ_OP_DISCARD) + if (bio->bi_rw & REQ_PREFLUSH || bio_op(bio) == REQ_OP_DISCARD) continue; rh_inc(rh, dm_rh_bio_to_region(rh, bio)); } diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 70bb0e8b62ce..69ab1ff5f5c9 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1680,7 +1680,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio) init_tracked_chunk(bio); - if (bio->bi_rw & REQ_FLUSH) { + if (bio->bi_rw & REQ_PREFLUSH) { bio->bi_bdev = s->cow->bdev; return DM_MAPIO_REMAPPED; } @@ -1799,7 +1799,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio) init_tracked_chunk(bio); - if (bio->bi_rw & REQ_FLUSH) { + if (bio->bi_rw & REQ_PREFLUSH) { if (!dm_bio_get_target_bio_nr(bio)) bio->bi_bdev = s->origin->bdev; else @@ -2285,7 +2285,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio) bio->bi_bdev = o->dev->bdev; - if (unlikely(bio->bi_rw & REQ_FLUSH)) + if (unlikely(bio->bi_rw & REQ_PREFLUSH)) return DM_MAPIO_REMAPPED; if (bio_rw(bio) != WRITE) diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index b738178ca068..48f1c01d7b9f 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -286,7 +286,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio) uint32_t stripe; unsigned target_bio_nr; - if (bio->bi_rw & REQ_FLUSH) { + if (bio->bi_rw & REQ_PREFLUSH) { target_bio_nr = dm_bio_get_target_bio_nr(bio); BUG_ON(target_bio_nr >= sc->stripes); bio->bi_bdev = sc->stripe[target_bio_nr].dev->bdev; diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 1b684cbb9ba2..5f9e3d799d66 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -697,7 +697,7 @@ static void remap_to_origin(struct thin_c *tc, struct bio *bio) static int bio_triggers_commit(struct thin_c *tc, struct bio *bio) { - return (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) && + return (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) && dm_thin_changed_this_transaction(tc->td); } @@ -868,7 +868,7 @@ static void __inc_remap_and_issue_cell(void *context, struct bio *bio; while ((bio = bio_list_pop(&cell->bios))) { - if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) || + if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA) || bio_op(bio) == REQ_OP_DISCARD) bio_list_add(&info->defer_bios, bio); else { @@ -1641,7 +1641,7 @@ static void __remap_and_issue_shared_cell(void *context, while ((bio = bio_list_pop(&cell->bios))) { if ((bio_data_dir(bio) == WRITE) || - (bio->bi_rw & (REQ_FLUSH | REQ_FUA) || + (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA) || bio_op(bio) == REQ_OP_DISCARD)) bio_list_add(&info->defer_bios, bio); else { @@ -2556,7 +2556,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_SUBMITTED; } - if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) || + if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA) || bio_op(bio) == REQ_OP_DISCARD) { thin_defer_bio_with_throttle(tc, bio); return DM_MAPIO_SUBMITTED; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index fcc68c8edba0..aba7ed9abb3a 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1003,12 +1003,12 @@ static void dec_pending(struct dm_io *io, int error) if (io_error == DM_ENDIO_REQUEUE) return; - if ((bio->bi_rw & REQ_FLUSH) && bio->bi_iter.bi_size) { + if ((bio->bi_rw & REQ_PREFLUSH) && bio->bi_iter.bi_size) { /* * Preflush done for flush with data, reissue - * without REQ_FLUSH. + * without REQ_PREFLUSH. */ - bio->bi_rw &= ~REQ_FLUSH; + bio->bi_rw &= ~REQ_PREFLUSH; queue_io(md, bio); } else { /* done with normal IO or empty flush */ @@ -1477,7 +1477,7 @@ EXPORT_SYMBOL_GPL(dm_set_target_max_io_len); /* * A target may call dm_accept_partial_bio only from the map routine. It is - * allowed for all bio types except REQ_FLUSH. + * allowed for all bio types except REQ_PREFLUSH. * * dm_accept_partial_bio informs the dm that the target only wants to process * additional n_sectors sectors of the bio and the rest of the data should be @@ -1507,7 +1507,7 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors) { struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone); unsigned bi_size = bio->bi_iter.bi_size >> SECTOR_SHIFT; - BUG_ON(bio->bi_rw & REQ_FLUSH); + BUG_ON(bio->bi_rw & REQ_PREFLUSH); BUG_ON(bi_size > *tio->len_ptr); BUG_ON(n_sectors > bi_size); *tio->len_ptr -= bi_size - n_sectors; @@ -1795,7 +1795,7 @@ static void __split_and_process_bio(struct mapped_device *md, start_io_acct(ci.io); - if (bio->bi_rw & REQ_FLUSH) { + if (bio->bi_rw & REQ_PREFLUSH) { ci.bio = &ci.md->flush_bio; ci.sector_count = 0; error = __send_empty_flush(&ci); diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 1ad3f485672c..70ff888d25d0 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -221,7 +221,7 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio) struct bio *split; sector_t start_sector, end_sector, data_offset; - if (unlikely(bio->bi_rw & REQ_FLUSH)) { + if (unlikely(bio->bi_rw & REQ_PREFLUSH)) { md_flush_request(mddev, bio); return; } diff --git a/drivers/md/md.c b/drivers/md/md.c index bd4844fe0e98..1f123f5a29da 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -414,7 +414,7 @@ static void md_submit_flush_data(struct work_struct *ws) /* an empty barrier - all done */ bio_endio(bio); else { - bio->bi_rw &= ~REQ_FLUSH; + bio->bi_rw &= ~REQ_PREFLUSH; mddev->pers->make_request(mddev, bio); } diff --git a/drivers/md/md.h b/drivers/md/md.h index 2e0918fc376d..b4f335245bd6 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -424,7 +424,7 @@ struct mddev { /* Generic flush handling. * The last to finish preflush schedules a worker to submit - * the rest of the request (without the REQ_FLUSH flag). + * the rest of the request (without the REQ_PREFLUSH flag). */ struct bio *flush_bio; atomic_t flush_pending; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index dd483bb2e111..72ea98e89e57 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -111,7 +111,7 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio) struct multipath_bh * mp_bh; struct multipath_info *multipath; - if (unlikely(bio->bi_rw & REQ_FLUSH)) { + if (unlikely(bio->bi_rw & REQ_PREFLUSH)) { md_flush_request(mddev, bio); return; } diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 051a10ca4e09..c3d439083212 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -458,7 +458,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio) struct md_rdev *tmp_dev; struct bio *split; - if (unlikely(bio->bi_rw & REQ_FLUSH)) { + if (unlikely(bio->bi_rw & REQ_PREFLUSH)) { md_flush_request(mddev, bio); return; } diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a3427230f7cf..10e53cd6a995 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1056,7 +1056,8 @@ static void raid1_make_request(struct mddev *mddev, struct bio * bio) const int op = bio_op(bio); const int rw = bio_data_dir(bio); const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); - const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); + const unsigned long do_flush_fua = (bio->bi_rw & + (REQ_PREFLUSH | REQ_FUA)); const unsigned long do_sec = (bio->bi_rw & REQ_SECURE); struct md_rdev *blocked_rdev; struct blk_plug_cb *cb; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 615045a11bac..245640b50153 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1447,7 +1447,7 @@ static void raid10_make_request(struct mddev *mddev, struct bio *bio) struct bio *split; - if (unlikely(bio->bi_rw & REQ_FLUSH)) { + if (unlikely(bio->bi_rw & REQ_PREFLUSH)) { md_flush_request(mddev, bio); return; } diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 92651381b094..5504ce2bac06 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -536,7 +536,7 @@ int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio) bio_endio(bio); return 0; } - bio->bi_rw &= ~REQ_FLUSH; + bio->bi_rw &= ~REQ_PREFLUSH; return -EAGAIN; } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index b9122e2c6aa1..7aacf5b55e15 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5150,7 +5150,7 @@ static void raid5_make_request(struct mddev *mddev, struct bio * bi) DEFINE_WAIT(w); bool do_prepare; - if (unlikely(bi->bi_rw & REQ_FLUSH)) { + if (unlikely(bi->bi_rw & REQ_PREFLUSH)) { int ret = r5l_handle_flush_request(conf->log, bi); if (ret == 0) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index da944ffddbaf..ca70bc78b27d 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -2207,7 +2207,7 @@ static void btrfsic_bio_end_io(struct bio *bp) block->dev_bytenr, block->mirror_num); next_block = block->next_in_same_bio; block->iodone_w_error = iodone_w_error; - if (block->submit_bio_bh_rw & REQ_FLUSH) { + if (block->submit_bio_bh_rw & REQ_PREFLUSH) { dev_state->last_flush_gen++; if ((dev_state->state->print_mask & BTRFSIC_PRINT_MASK_END_IO_BIO_BH)) @@ -2243,7 +2243,7 @@ static void btrfsic_bh_end_io(struct buffer_head *bh, int uptodate) block->dev_bytenr, block->mirror_num); block->iodone_w_error = iodone_w_error; - if (block->submit_bio_bh_rw & REQ_FLUSH) { + if (block->submit_bio_bh_rw & REQ_PREFLUSH) { dev_state->last_flush_gen++; if ((dev_state->state->print_mask & BTRFSIC_PRINT_MASK_END_IO_BIO_BH)) @@ -2884,7 +2884,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh) btrfsic_process_written_block(dev_state, dev_bytenr, &bh->b_data, 1, NULL, NULL, bh, op_flags); - } else if (NULL != dev_state && (op_flags & REQ_FLUSH)) { + } else if (NULL != dev_state && (op_flags & REQ_PREFLUSH)) { if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) printk(KERN_INFO @@ -2982,7 +2982,7 @@ static void __btrfsic_submit_bio(struct bio *bio) kunmap(bio->bi_io_vec[i].bv_page); } kfree(mapped_datav); - } else if (NULL != dev_state && (bio->bi_rw & REQ_FLUSH)) { + } else if (NULL != dev_state && (bio->bi_rw & REQ_PREFLUSH)) { if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) printk(KERN_INFO diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 34bc99637d5a..dc68f562f681 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1354,7 +1354,7 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags) trace_jbd2_write_superblock(journal, write_flags); if (!(journal->j_flags & JBD2_BARRIER)) - write_flags &= ~(REQ_FUA | REQ_FLUSH); + write_flags &= ~(REQ_FUA | REQ_PREFLUSH); lock_buffer(bh); if (buffer_write_io_error(bh)) { /* diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index d8acd3716dbd..686d8f160f5c 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1237,7 +1237,7 @@ _xfs_buf_ioapply( if (bp->b_flags & XBF_FUA) op_flags |= REQ_FUA; if (bp->b_flags & XBF_FLUSH) - op_flags |= REQ_FLUSH; + op_flags |= REQ_PREFLUSH; /* * Run the write verifier callback function if it exists. If diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 32d87522f349..562ab8301217 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -168,7 +168,7 @@ enum rq_flag_bits { __REQ_NOIDLE, /* don't anticipate more IO after this one */ __REQ_INTEGRITY, /* I/O includes block integrity payload */ __REQ_FUA, /* forced unit access */ - __REQ_FLUSH, /* request for cache flush */ + __REQ_PREFLUSH, /* request for cache flush */ /* bio only flags */ __REQ_RAHEAD, /* read ahead, can fail anytime */ @@ -212,12 +212,12 @@ enum rq_flag_bits { (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) #define REQ_COMMON_MASK \ (REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | REQ_NOIDLE | \ - REQ_FLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE) + REQ_PREFLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE) #define REQ_CLONE_MASK REQ_COMMON_MASK /* This mask is used for both bio and request merge checking */ #define REQ_NOMERGE_FLAGS \ - (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ) + (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_PREFLUSH | REQ_FUA | REQ_FLUSH_SEQ) #define REQ_RAHEAD (1ULL << __REQ_RAHEAD) #define REQ_THROTTLED (1ULL << __REQ_THROTTLED) @@ -235,7 +235,7 @@ enum rq_flag_bits { #define REQ_PREEMPT (1ULL << __REQ_PREEMPT) #define REQ_ALLOCED (1ULL << __REQ_ALLOCED) #define REQ_COPY_USER (1ULL << __REQ_COPY_USER) -#define REQ_FLUSH (1ULL << __REQ_FLUSH) +#define REQ_PREFLUSH (1ULL << __REQ_PREFLUSH) #define REQ_FLUSH_SEQ (1ULL << __REQ_FLUSH_SEQ) #define REQ_IO_STAT (1ULL << __REQ_IO_STAT) #define REQ_MIXED_MERGE (1ULL << __REQ_MIXED_MERGE) diff --git a/include/linux/fs.h b/include/linux/fs.h index ccd166477487..183024525d40 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -204,9 +204,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, #define READ_SYNC REQ_SYNC #define WRITE_SYNC (REQ_SYNC | REQ_NOIDLE) #define WRITE_ODIRECT REQ_SYNC -#define WRITE_FLUSH (REQ_SYNC | REQ_NOIDLE | REQ_FLUSH) +#define WRITE_FLUSH (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH) #define WRITE_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FUA) -#define WRITE_FLUSH_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA) +#define WRITE_FLUSH_FUA (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH | REQ_FUA) /* * Attribute flags. These should be or-ed together to figure out what diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 30efa44a473c..878963a1f058 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -33,7 +33,7 @@ TRACE_DEFINE_ENUM(SSR); TRACE_DEFINE_ENUM(__REQ_RAHEAD); TRACE_DEFINE_ENUM(__REQ_SYNC); TRACE_DEFINE_ENUM(__REQ_NOIDLE); -TRACE_DEFINE_ENUM(__REQ_FLUSH); +TRACE_DEFINE_ENUM(__REQ_PREFLUSH); TRACE_DEFINE_ENUM(__REQ_FUA); TRACE_DEFINE_ENUM(__REQ_PRIO); TRACE_DEFINE_ENUM(__REQ_META); diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 0c70fbb6ea8d..03b0dd98ff0e 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -189,6 +189,7 @@ static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) }; #define BLK_TC_RAHEAD BLK_TC_AHEAD +#define BLK_TC_PREFLUSH BLK_TC_FLUSH /* The ilog2() calls fall out because they're constant */ #define MASK_TC_BIT(rw, __name) ((rw & REQ_ ## __name) << \ @@ -219,7 +220,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= MASK_TC_BIT(op_flags, SYNC); what |= MASK_TC_BIT(op_flags, RAHEAD); what |= MASK_TC_BIT(op_flags, META); - what |= MASK_TC_BIT(op_flags, FLUSH); + what |= MASK_TC_BIT(op_flags, PREFLUSH); what |= MASK_TC_BIT(op_flags, FUA); if (op == REQ_OP_DISCARD) what |= BLK_TC_ACT(BLK_TC_DISCARD); @@ -1779,7 +1780,7 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes) { int i = 0; - if (rw & REQ_FLUSH) + if (rw & REQ_PREFLUSH) rwbs[i++] = 'F'; switch (op) { -- cgit v1.3-14-g43fede From 6b90bd4ba40b38dc13c2782469c1c77e4ed79915 Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Tue, 24 May 2016 00:09:38 +0200 Subject: GCC plugin infrastructure This patch allows to build the whole kernel with GCC plugins. It was ported from grsecurity/PaX. The infrastructure supports building out-of-tree modules and building in a separate directory. Cross-compilation is supported too. Currently the x86, arm, arm64 and uml architectures enable plugins. The directory of the gcc plugins is scripts/gcc-plugins. You can use a file or a directory there. The plugins compile with these options: * -fno-rtti: gcc is compiled with this option so the plugins must use it too * -fno-exceptions: this is inherited from gcc too * -fasynchronous-unwind-tables: this is inherited from gcc too * -ggdb: it is useful for debugging a plugin (better backtrace on internal errors) * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h) * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version variable, plugin-version.h) The infrastructure introduces a new Makefile target called gcc-plugins. It supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++). This script also checks the availability of the included headers in scripts/gcc-plugins/gcc-common.h. The gcc-common.h header contains frequently included headers for GCC plugins and it has a compatibility layer for the supported gcc versions. The gcc-generate-*-pass.h headers automatically generate the registration structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes. Note that 'make clean' keeps the *.so files (only the distclean or mrproper targets clean all) because they are needed for out-of-tree modules. Based on work created by the PaX Team. Signed-off-by: Emese Revfy Acked-by: Kees Cook Signed-off-by: Michal Marek --- .gitignore | 1 + Documentation/dontdiff | 1 + Documentation/gcc-plugins.txt | 87 +++ MAINTAINERS | 9 + Makefile | 14 +- arch/Kconfig | 15 + arch/arm/Kconfig | 1 + arch/arm64/Kconfig | 1 + arch/um/Kconfig.common | 1 + arch/x86/Kconfig | 1 + arch/x86/entry/vdso/Makefile | 3 +- scripts/Makefile | 2 +- scripts/Makefile.gcc-plugins | 23 + scripts/gcc-plugin.sh | 51 ++ scripts/gcc-plugins/Makefile | 20 + scripts/gcc-plugins/gcc-common.h | 830 +++++++++++++++++++++ scripts/gcc-plugins/gcc-generate-gimple-pass.h | 175 +++++ scripts/gcc-plugins/gcc-generate-ipa-pass.h | 289 +++++++ scripts/gcc-plugins/gcc-generate-rtl-pass.h | 175 +++++ scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 175 +++++ scripts/link-vmlinux.sh | 2 +- scripts/package/builddeb | 1 + 22 files changed, 1872 insertions(+), 5 deletions(-) create mode 100644 Documentation/gcc-plugins.txt create mode 100644 scripts/Makefile.gcc-plugins create mode 100755 scripts/gcc-plugin.sh create mode 100644 scripts/gcc-plugins/Makefile create mode 100644 scripts/gcc-plugins/gcc-common.h create mode 100644 scripts/gcc-plugins/gcc-generate-gimple-pass.h create mode 100644 scripts/gcc-plugins/gcc-generate-ipa-pass.h create mode 100644 scripts/gcc-plugins/gcc-generate-rtl-pass.h create mode 100644 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h (limited to 'Documentation') diff --git a/.gitignore b/.gitignore index 0c320bf02586..2be25f771bd8 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ modules.builtin Module.symvers *.dwo *.su +*.c.[012]*.* # # Top-level generic files diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 8ea834f6b289..5385cba941d2 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -3,6 +3,7 @@ *.bc *.bin *.bz2 +*.c.[012]*.* *.cis *.cpio *.csp diff --git a/Documentation/gcc-plugins.txt b/Documentation/gcc-plugins.txt new file mode 100644 index 000000000000..891c69464434 --- /dev/null +++ b/Documentation/gcc-plugins.txt @@ -0,0 +1,87 @@ +GCC plugin infrastructure +========================= + + +1. Introduction +=============== + +GCC plugins are loadable modules that provide extra features to the +compiler [1]. They are useful for runtime instrumentation and static analysis. +We can analyse, change and add further code during compilation via +callbacks [2], GIMPLE [3], IPA [4] and RTL passes [5]. + +The GCC plugin infrastructure of the kernel supports all gcc versions from +4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a +separate directory. +Plugin source files have to be compilable by both a C and a C++ compiler as well +because gcc versions 4.5 and 4.6 are compiled by a C compiler, +gcc-4.7 can be compiled by a C or a C++ compiler, +and versions 4.8+ can only be compiled by a C++ compiler. + +Currently the GCC plugin infrastructure supports only the x86, arm and arm64 +architectures. + +This infrastructure was ported from grsecurity [6] and PaX [7]. + +-- +[1] https://gcc.gnu.org/onlinedocs/gccint/Plugins.html +[2] https://gcc.gnu.org/onlinedocs/gccint/Plugin-API.html#Plugin-API +[3] https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html +[4] https://gcc.gnu.org/onlinedocs/gccint/IPA.html +[5] https://gcc.gnu.org/onlinedocs/gccint/RTL.html +[6] https://grsecurity.net/ +[7] https://pax.grsecurity.net/ + + +2. Files +======== + +$(src)/scripts/gcc-plugins + This is the directory of the GCC plugins. + +$(src)/scripts/gcc-plugins/gcc-common.h + This is a compatibility header for GCC plugins. + It should be always included instead of individual gcc headers. + +$(src)/scripts/gcc-plugin.sh + This script checks the availability of the included headers in + gcc-common.h and chooses the proper host compiler to build the plugins + (gcc-4.7 can be built by either gcc or g++). + +$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h +$(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h +$(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h +$(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h + These headers automatically generate the registration structures for + GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions + from 4.5 to 6.0. + They should be preferred to creating the structures by hand. + + +3. Usage +======== + +You must install the gcc plugin headers for your gcc version, +e.g., on Ubuntu for gcc-4.9: + + apt-get install gcc-4.9-plugin-dev + +Enable a GCC plugin based feature in the kernel config: + + CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y + +To compile only the plugin(s): + + make gcc-plugins + +or just run the kernel make and compile the whole kernel with +the cyclomatic complexity GCC plugin. + + +4. How to add a new GCC plugin +============================== + +The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a directory +here. It must be added to $(src)/scripts/gcc-plugins/Makefile, +$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig. +See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin. diff --git a/MAINTAINERS b/MAINTAINERS index 7304d2e37a98..94a19add522d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4979,6 +4979,15 @@ L: linux-scsi@vger.kernel.org S: Odd Fixes (e.g., new signatures) F: drivers/scsi/fdomain.* +GCC PLUGINS +M: Kees Cook +R: Emese Revfy +L: kernel-hardening@lists.openwall.com +S: Maintained +F: scripts/gcc-plugins/ +F: scripts/gcc-plugin.sh +F: Documentation/gcc-plugins.txt + GCOV BASED KERNEL PROFILING M: Peter Oberparleiter S: Maintained diff --git a/Makefile b/Makefile index 0f70de63cfdb..20fcf4b26fbc 100644 --- a/Makefile +++ b/Makefile @@ -552,7 +552,7 @@ ifeq ($(KBUILD_EXTMOD),) # in parallel PHONY += scripts scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ - asm-generic + asm-generic gcc-plugins $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -631,6 +631,15 @@ endif # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) +PHONY += gcc-plugins +gcc-plugins: scripts_basic +ifdef CONFIG_GCC_PLUGINS + $(Q)$(MAKE) $(build)=scripts/gcc-plugins +endif + @: + +include scripts/Makefile.gcc-plugins + ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -1026,7 +1035,7 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ archprepare: archheaders archscripts prepare1 scripts_basic -prepare0: archprepare +prepare0: archprepare gcc-plugins $(Q)$(MAKE) $(build)=. # All the preparing.. @@ -1507,6 +1516,7 @@ clean: $(clean-dirs) -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ -o -name modules.builtin -o -name '.tmp_*.o.*' \ + -o -name '*.c.[012]*.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # Generate tags for editors diff --git a/arch/Kconfig b/arch/Kconfig index d794384a0404..1b93632198fa 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -357,6 +357,21 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_GCC_PLUGINS + bool + help + An arch should select this symbol if it supports building with + GCC plugins. + +menuconfig GCC_PLUGINS + bool "GCC plugins" + depends on HAVE_GCC_PLUGINS + help + GCC plugins are loadable modules that provide extra features to the + compiler. They are useful for runtime instrumentation and static analysis. + + See Documentation/gcc-plugins.txt for details. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 90542db1220d..ce590468ffa2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -54,6 +54,7 @@ config ARM select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) + select HAVE_GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_IDE if PCI || ISA || PCMCIA diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 76747d92bc72..24e7bd6778ea 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -76,6 +76,7 @@ config ARM64 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index cc0013475444..58650d098fb4 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -9,6 +9,7 @@ config UML select GENERIC_CPU_DEVICES select GENERIC_IO select GENERIC_CLOCKEVENTS + select HAVE_GCC_PLUGINS select TTY # Needed for line.c config MMU diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0a7b885964ba..65e7701bd429 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -111,6 +111,7 @@ config X86 select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER + select HAVE_GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_HW_BREAKPOINT select HAVE_IDE diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 253b72eaade6..f9123163a850 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -75,7 +75,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ -fno-omit-frame-pointer -foptimize-sibling-calls \ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO -$(vobjs): KBUILD_CFLAGS += $(CFL) +$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) # # vDSO code runs in userspace and -pg doesn't help with profiling anyway. @@ -145,6 +145,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) diff --git a/scripts/Makefile b/scripts/Makefile index 822ab4a6a4aa..1d80897a9644 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -47,4 +47,4 @@ subdir-$(CONFIG_DTC) += dtc subdir-$(CONFIG_GDB_SCRIPTS) += gdb # Let clean descend into subdirs -subdir- += basic kconfig package +subdir- += basic kconfig package gcc-plugins diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins new file mode 100644 index 000000000000..bcc373dcb3b5 --- /dev/null +++ b/scripts/Makefile.gcc-plugins @@ -0,0 +1,23 @@ +ifdef CONFIG_GCC_PLUGINS + __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) + PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") + + GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) + + export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN + + ifeq ($(PLUGINCC),) + ifneq ($(GCC_PLUGINS_CFLAGS),) + ifeq ($(call cc-ifversion, -ge, 0405, y), y) + PLUGINCC := $(shell $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") + $(warning warning: your gcc installation does not support plugins, perhaps the necessary headers are missing?) + else + $(warning warning: your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least) + endif + endif + endif + + KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) + GCC_PLUGIN := $(gcc-plugin-y) + +endif diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh new file mode 100755 index 000000000000..fb9207565471 --- /dev/null +++ b/scripts/gcc-plugin.sh @@ -0,0 +1,51 @@ +#!/bin/sh +srctree=$(dirname "$0") +gccplugins_dir=$($3 -print-file-name=plugin) +plugincc=$($1 -E -x c++ - -o /dev/null -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <= 4008 || defined(ENABLE_BUILD_WITH_CXX) +#warning $2 CXX +#else +#warning $1 CC +#endif +EOF +) + +if [ $? -ne 0 ] +then + exit 1 +fi + +case "$plugincc" in + *"$1 CC"*) + echo "$1" + exit 0 + ;; + + *"$2 CXX"*) + # the c++ compiler needs another test, see below + ;; + + *) + exit 1 + ;; +esac + +# we need a c++ compiler that supports the designated initializer GNU extension +plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <= 6000 +#include "gcc-plugin.h" +#else +#include "plugin.h" +#endif +#include "plugin-version.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "line-map.h" +#include "input.h" +#include "tree.h" + +#include "tree-inline.h" +#include "version.h" +#include "rtl.h" +#include "tm_p.h" +#include "flags.h" +#include "hard-reg-set.h" +#include "output.h" +#include "except.h" +#include "function.h" +#include "toplev.h" +#include "basic-block.h" +#include "intl.h" +#include "ggc.h" +#include "timevar.h" + +#include "params.h" + +#if BUILDING_GCC_VERSION <= 4009 +#include "pointer-set.h" +#else +#include "hash-map.h" +#endif + +#include "emit-rtl.h" +#include "debug.h" +#include "target.h" +#include "langhooks.h" +#include "cfgloop.h" +#include "cgraph.h" +#include "opts.h" + +#if BUILDING_GCC_VERSION == 4005 +#include +#endif + +#if BUILDING_GCC_VERSION >= 4007 +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" +#endif + +#if BUILDING_GCC_VERSION >= 4006 +#include "c-family/c-common.h" +#else +#include "c-common.h" +#endif + +#if BUILDING_GCC_VERSION <= 4008 +#include "tree-flow.h" +#else +#include "tree-cfgcleanup.h" +#include "tree-ssa-operands.h" +#include "tree-into-ssa.h" +#endif + +#if BUILDING_GCC_VERSION >= 4008 +#include "is-a.h" +#endif + +#include "diagnostic.h" +#include "tree-dump.h" +#include "tree-pass.h" +#include "predict.h" +#include "ipa-utils.h" + +#if BUILDING_GCC_VERSION >= 4009 +#include "attribs.h" +#include "varasm.h" +#include "stor-layout.h" +#include "internal-fn.h" +#include "gimple-expr.h" +#include "gimple-fold.h" +#include "context.h" +#include "tree-ssa-alias.h" +#include "tree-ssa.h" +#include "stringpool.h" +#include "tree-ssanames.h" +#include "print-tree.h" +#include "tree-eh.h" +#include "stmt.h" +#include "gimplify.h" +#endif + +#include "gimple.h" + +#if BUILDING_GCC_VERSION >= 4009 +#include "tree-ssa-operands.h" +#include "tree-phinodes.h" +#include "tree-cfg.h" +#include "gimple-iterator.h" +#include "gimple-ssa.h" +#include "ssa-iterators.h" +#endif + +#if BUILDING_GCC_VERSION >= 5000 +#include "builtins.h" +#endif + +/* #include "expr.h" where are you... */ +extern rtx emit_move_insn(rtx x, rtx y); + +/* missing from basic_block.h... */ +extern void debug_dominance_info(enum cdi_direction dir); +extern void debug_dominance_tree(enum cdi_direction dir, basic_block root); + +#if BUILDING_GCC_VERSION == 4006 +extern void debug_gimple_stmt(gimple); +extern void debug_gimple_seq(gimple_seq); +extern void print_gimple_seq(FILE *, gimple_seq, int, int); +extern void print_gimple_stmt(FILE *, gimple, int, int); +extern void print_gimple_expr(FILE *, gimple, int, int); +extern void dump_gimple_stmt(pretty_printer *, gimple, int, int); +#endif + +#define __unused __attribute__((__unused__)) + +#define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node)) +#define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node)) +#define TYPE_NAME_POINTER(node) IDENTIFIER_POINTER(TYPE_NAME(node)) +#define TYPE_NAME_LENGTH(node) IDENTIFIER_LENGTH(TYPE_NAME(node)) + +/* should come from c-tree.h if only it were installed for gcc 4.5... */ +#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE) + +#if BUILDING_GCC_VERSION == 4005 +#define FOR_EACH_LOCAL_DECL(FUN, I, D) \ + for (tree vars = (FUN)->local_decls, (I) = 0; \ + vars && ((D) = TREE_VALUE(vars)); \ + vars = TREE_CHAIN(vars), (I)++) +#define DECL_CHAIN(NODE) (TREE_CHAIN(DECL_MINIMAL_CHECK(NODE))) +#define FOR_EACH_VEC_ELT(T, V, I, P) \ + for (I = 0; VEC_iterate(T, (V), (I), (P)); ++(I)) +#define TODO_rebuild_cgraph_edges 0 +#define SCOPE_FILE_SCOPE_P(EXP) (!(EXP)) + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +typedef struct varpool_node *varpool_node_ptr; + +static inline bool gimple_call_builtin_p(gimple stmt, enum built_in_function code) +{ + tree fndecl; + + if (!is_gimple_call(stmt)) + return false; + fndecl = gimple_call_fndecl(stmt); + if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL) + return false; + return DECL_FUNCTION_CODE(fndecl) == code; +} + +static inline bool is_simple_builtin(tree decl) +{ + if (decl && DECL_BUILT_IN_CLASS(decl) != BUILT_IN_NORMAL) + return false; + + switch (DECL_FUNCTION_CODE(decl)) { + /* Builtins that expand to constants. */ + case BUILT_IN_CONSTANT_P: + case BUILT_IN_EXPECT: + case BUILT_IN_OBJECT_SIZE: + case BUILT_IN_UNREACHABLE: + /* Simple register moves or loads from stack. */ + case BUILT_IN_RETURN_ADDRESS: + case BUILT_IN_EXTRACT_RETURN_ADDR: + case BUILT_IN_FROB_RETURN_ADDR: + case BUILT_IN_RETURN: + case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: + case BUILT_IN_FRAME_ADDRESS: + case BUILT_IN_VA_END: + case BUILT_IN_STACK_SAVE: + case BUILT_IN_STACK_RESTORE: + /* Exception state returns or moves registers around. */ + case BUILT_IN_EH_FILTER: + case BUILT_IN_EH_POINTER: + case BUILT_IN_EH_COPY_VALUES: + return true; + + default: + return false; + } +} + +static inline void add_local_decl(struct function *fun, tree d) +{ + gcc_assert(TREE_CODE(d) == VAR_DECL); + fun->local_decls = tree_cons(NULL_TREE, d, fun->local_decls); +} +#endif + +#if BUILDING_GCC_VERSION <= 4006 +#define ANY_RETURN_P(rtx) (GET_CODE(rtx) == RETURN) +#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4(EXP) +#define EDGE_PRESERVE 0ULL +#define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x" +#define flag_fat_lto_objects true + +#define get_random_seed(noinit) ({ \ + unsigned HOST_WIDE_INT seed; \ + sscanf(get_random_seed(noinit), "%" HOST_WIDE_INT_PRINT "x", &seed); \ + seed * seed; }) + +#define int_const_binop(code, arg1, arg2) \ + int_const_binop((code), (arg1), (arg2), 0) + +static inline bool gimple_clobber_p(gimple s __unused) +{ + return false; +} + +static inline bool gimple_asm_clobbers_memory_p(const_gimple stmt) +{ + unsigned i; + + for (i = 0; i < gimple_asm_nclobbers(stmt); i++) { + tree op = gimple_asm_clobber_op(stmt, i); + + if (!strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "memory")) + return true; + } + + return false; +} + +static inline tree builtin_decl_implicit(enum built_in_function fncode) +{ + return implicit_built_in_decls[fncode]; +} + +static inline int ipa_reverse_postorder(struct cgraph_node **order) +{ + return cgraph_postorder(order); +} + +static inline struct cgraph_node *cgraph_create_node(tree decl) +{ + return cgraph_node(decl); +} + +static inline struct cgraph_node *cgraph_get_create_node(tree decl) +{ + struct cgraph_node *node = cgraph_get_node(decl); + + return node ? node : cgraph_node(decl); +} + +static inline bool cgraph_function_with_gimple_body_p(struct cgraph_node *node) +{ + return node->analyzed && !node->thunk.thunk_p && !node->alias; +} + +static inline struct cgraph_node *cgraph_first_function_with_gimple_body(void) +{ + struct cgraph_node *node; + + for (node = cgraph_nodes; node; node = node->next) + if (cgraph_function_with_gimple_body_p(node)) + return node; + return NULL; +} + +static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct cgraph_node *node) +{ + for (node = node->next; node; node = node->next) + if (cgraph_function_with_gimple_body_p(node)) + return node; + return NULL; +} + +#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \ + for ((node) = cgraph_first_function_with_gimple_body(); (node); \ + (node) = cgraph_next_function_with_gimple_body(node)) + +static inline void varpool_add_new_variable(tree decl) +{ + varpool_finalize_decl(decl); +} +#endif + +#if BUILDING_GCC_VERSION <= 4007 +#define FOR_EACH_FUNCTION(node) \ + for (node = cgraph_nodes; node; node = node->next) +#define FOR_EACH_VARIABLE(node) \ + for (node = varpool_nodes; node; node = node->next) +#define PROP_loops 0 +#define NODE_SYMBOL(node) (node) +#define NODE_DECL(node) (node)->decl +#define INSN_LOCATION(INSN) RTL_LOCATION(INSN) +#define vNULL NULL + +static inline int bb_loop_depth(const_basic_block bb) +{ + return bb->loop_father ? loop_depth(bb->loop_father) : 0; +} + +static inline bool gimple_store_p(gimple gs) +{ + tree lhs = gimple_get_lhs(gs); + + return lhs && !is_gimple_reg(lhs); +} + +static inline void gimple_init_singleton(gimple g __unused) +{ +} +#endif + +#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008 +static inline struct cgraph_node *cgraph_alias_target(struct cgraph_node *n) +{ + return cgraph_alias_aliased_node(n); +} +#endif + +#if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION <= 4009 +#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ + cgraph_create_edge((caller), (callee), (call_stmt), (count), (freq)) +#define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \ + cgraph_create_edge_including_clones((caller), (callee), (old_call_stmt), (call_stmt), (count), (freq), (reason)) +#endif + +#if BUILDING_GCC_VERSION <= 4008 +#define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) +#define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN) +#define basic_block_info_for_fn(FN) ((FN)->cfg->x_basic_block_info) +#define n_basic_blocks_for_fn(FN) ((FN)->cfg->x_n_basic_blocks) +#define n_edges_for_fn(FN) ((FN)->cfg->x_n_edges) +#define last_basic_block_for_fn(FN) ((FN)->cfg->x_last_basic_block) +#define label_to_block_map_for_fn(FN) ((FN)->cfg->x_label_to_block_map) +#define profile_status_for_fn(FN) ((FN)->cfg->x_profile_status) +#define BASIC_BLOCK_FOR_FN(FN, N) BASIC_BLOCK_FOR_FUNCTION((FN), (N)) +#define NODE_IMPLICIT_ALIAS(node) (node)->same_body_alias +#define VAR_P(NODE) (TREE_CODE(NODE) == VAR_DECL) + +static inline bool tree_fits_shwi_p(const_tree t) +{ + if (t == NULL_TREE || TREE_CODE(t) != INTEGER_CST) + return false; + + if (TREE_INT_CST_HIGH(t) == 0 && (HOST_WIDE_INT)TREE_INT_CST_LOW(t) >= 0) + return true; + + if (TREE_INT_CST_HIGH(t) == -1 && (HOST_WIDE_INT)TREE_INT_CST_LOW(t) < 0 && !TYPE_UNSIGNED(TREE_TYPE(t))) + return true; + + return false; +} + +static inline bool tree_fits_uhwi_p(const_tree t) +{ + if (t == NULL_TREE || TREE_CODE(t) != INTEGER_CST) + return false; + + return TREE_INT_CST_HIGH(t) == 0; +} + +static inline HOST_WIDE_INT tree_to_shwi(const_tree t) +{ + gcc_assert(tree_fits_shwi_p(t)); + return TREE_INT_CST_LOW(t); +} + +static inline unsigned HOST_WIDE_INT tree_to_uhwi(const_tree t) +{ + gcc_assert(tree_fits_uhwi_p(t)); + return TREE_INT_CST_LOW(t); +} + +static inline const char *get_tree_code_name(enum tree_code code) +{ + gcc_assert(code < MAX_TREE_CODES); + return tree_code_name[code]; +} + +#define ipa_remove_stmt_references(cnode, stmt) + +typedef union gimple_statement_d gasm; +typedef union gimple_statement_d gassign; +typedef union gimple_statement_d gcall; +typedef union gimple_statement_d gcond; +typedef union gimple_statement_d gdebug; +typedef union gimple_statement_d gphi; +typedef union gimple_statement_d greturn; + +static inline gasm *as_a_gasm(gimple stmt) +{ + return stmt; +} + +static inline const gasm *as_a_const_gasm(const_gimple stmt) +{ + return stmt; +} + +static inline gassign *as_a_gassign(gimple stmt) +{ + return stmt; +} + +static inline const gassign *as_a_const_gassign(const_gimple stmt) +{ + return stmt; +} + +static inline gcall *as_a_gcall(gimple stmt) +{ + return stmt; +} + +static inline const gcall *as_a_const_gcall(const_gimple stmt) +{ + return stmt; +} + +static inline gcond *as_a_gcond(gimple stmt) +{ + return stmt; +} + +static inline const gcond *as_a_const_gcond(const_gimple stmt) +{ + return stmt; +} + +static inline gdebug *as_a_gdebug(gimple stmt) +{ + return stmt; +} + +static inline const gdebug *as_a_const_gdebug(const_gimple stmt) +{ + return stmt; +} + +static inline gphi *as_a_gphi(gimple stmt) +{ + return stmt; +} + +static inline const gphi *as_a_const_gphi(const_gimple stmt) +{ + return stmt; +} + +static inline greturn *as_a_greturn(gimple stmt) +{ + return stmt; +} + +static inline const greturn *as_a_const_greturn(const_gimple stmt) +{ + return stmt; +} +#endif + +#if BUILDING_GCC_VERSION == 4008 +#define NODE_SYMBOL(node) (&(node)->symbol) +#define NODE_DECL(node) (node)->symbol.decl +#endif + +#if BUILDING_GCC_VERSION >= 4008 +#define add_referenced_var(var) +#define mark_sym_for_renaming(var) +#define varpool_mark_needed_node(node) +#define create_var_ann(var) +#define TODO_dump_func 0 +#define TODO_dump_cgraph 0 +#endif + +#if BUILDING_GCC_VERSION <= 4009 +#define TODO_verify_il 0 +#define AVAIL_INTERPOSABLE AVAIL_OVERWRITABLE + +#define section_name_prefix LTO_SECTION_NAME_PREFIX +#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__) + +typedef struct rtx_def rtx_insn; + +static inline void set_decl_section_name(tree node, const char *value) +{ + if (value) + DECL_SECTION_NAME(node) = build_string(strlen(value) + 1, value); + else + DECL_SECTION_NAME(node) = NULL; +} +#endif + +#if BUILDING_GCC_VERSION == 4009 +typedef struct gimple_statement_asm gasm; +typedef struct gimple_statement_base gassign; +typedef struct gimple_statement_call gcall; +typedef struct gimple_statement_base gcond; +typedef struct gimple_statement_base gdebug; +typedef struct gimple_statement_phi gphi; +typedef struct gimple_statement_base greturn; + +static inline gasm *as_a_gasm(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gasm *as_a_const_gasm(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline gassign *as_a_gassign(gimple stmt) +{ + return stmt; +} + +static inline const gassign *as_a_const_gassign(const_gimple stmt) +{ + return stmt; +} + +static inline gcall *as_a_gcall(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gcall *as_a_const_gcall(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline gcond *as_a_gcond(gimple stmt) +{ + return stmt; +} + +static inline const gcond *as_a_const_gcond(const_gimple stmt) +{ + return stmt; +} + +static inline gdebug *as_a_gdebug(gimple stmt) +{ + return stmt; +} + +static inline const gdebug *as_a_const_gdebug(const_gimple stmt) +{ + return stmt; +} + +static inline gphi *as_a_gphi(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gphi *as_a_const_gphi(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline greturn *as_a_greturn(gimple stmt) +{ + return stmt; +} + +static inline const greturn *as_a_const_greturn(const_gimple stmt) +{ + return stmt; +} +#endif + +#if BUILDING_GCC_VERSION >= 4009 +#define TODO_ggc_collect 0 +#define NODE_SYMBOL(node) (node) +#define NODE_DECL(node) (node)->decl +#define cgraph_node_name(node) (node)->name() +#define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias +#endif + +#if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000 +/* gimple related */ +template <> +template <> +inline bool is_a_helper::test(const_gimple gs) +{ + return gs->code == GIMPLE_ASSIGN; +} +#endif + +#if BUILDING_GCC_VERSION >= 5000 +#define TODO_verify_ssa TODO_verify_il +#define TODO_verify_flow TODO_verify_il +#define TODO_verify_stmts TODO_verify_il +#define TODO_verify_rtl_sharing TODO_verify_il + +#define INSN_DELETED_P(insn) (insn)->deleted() + +/* symtab/cgraph related */ +#define debug_cgraph_node(node) (node)->debug() +#define cgraph_get_node(decl) cgraph_node::get(decl) +#define cgraph_get_create_node(decl) cgraph_node::get_create(decl) +#define cgraph_create_node(decl) cgraph_node::create(decl) +#define cgraph_n_nodes symtab->cgraph_count +#define cgraph_max_uid symtab->cgraph_max_uid +#define varpool_get_node(decl) varpool_node::get(decl) + +#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ + (caller)->create_edge((callee), (call_stmt), (count), (freq)) +#define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \ + (caller)->create_edge_including_clones((callee), (old_call_stmt), (call_stmt), (count), (freq), (reason)) + +typedef struct cgraph_node *cgraph_node_ptr; +typedef struct cgraph_edge *cgraph_edge_p; +typedef struct varpool_node *varpool_node_ptr; + +static inline void change_decl_assembler_name(tree decl, tree name) +{ + symtab->change_decl_assembler_name(decl, name); +} + +static inline void varpool_finalize_decl(tree decl) +{ + varpool_node::finalize_decl(decl); +} + +static inline void varpool_add_new_variable(tree decl) +{ + varpool_node::add(decl); +} + +static inline unsigned int rebuild_cgraph_edges(void) +{ + return cgraph_edge::rebuild_edges(); +} + +static inline cgraph_node_ptr cgraph_function_node(cgraph_node_ptr node, enum availability *availability) +{ + return node->function_symbol(availability); +} + +static inline cgraph_node_ptr cgraph_function_or_thunk_node(cgraph_node_ptr node, enum availability *availability = NULL) +{ + return node->ultimate_alias_target(availability); +} + +static inline bool cgraph_only_called_directly_p(cgraph_node_ptr node) +{ + return node->only_called_directly_p(); +} + +static inline enum availability cgraph_function_body_availability(cgraph_node_ptr node) +{ + return node->get_availability(); +} + +static inline cgraph_node_ptr cgraph_alias_target(cgraph_node_ptr node) +{ + return node->get_alias_target(); +} + +static inline struct cgraph_node_hook_list *cgraph_add_function_insertion_hook(cgraph_node_hook hook, void *data) +{ + return symtab->add_cgraph_insertion_hook(hook, data); +} + +static inline void cgraph_remove_function_insertion_hook(struct cgraph_node_hook_list *entry) +{ + symtab->remove_cgraph_insertion_hook(entry); +} + +static inline struct cgraph_node_hook_list *cgraph_add_node_removal_hook(cgraph_node_hook hook, void *data) +{ + return symtab->add_cgraph_removal_hook(hook, data); +} + +static inline void cgraph_remove_node_removal_hook(struct cgraph_node_hook_list *entry) +{ + symtab->remove_cgraph_removal_hook(entry); +} + +static inline struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook(cgraph_2node_hook hook, void *data) +{ + return symtab->add_cgraph_duplication_hook(hook, data); +} + +static inline void cgraph_remove_node_duplication_hook(struct cgraph_2node_hook_list *entry) +{ + symtab->remove_cgraph_duplication_hook(entry); +} + +static inline void cgraph_call_node_duplication_hooks(cgraph_node_ptr node, cgraph_node_ptr node2) +{ + symtab->call_cgraph_duplication_hooks(node, node2); +} + +static inline void cgraph_call_edge_duplication_hooks(cgraph_edge *cs1, cgraph_edge *cs2) +{ + symtab->call_edge_duplication_hooks(cs1, cs2); +} + +#if BUILDING_GCC_VERSION >= 6000 +typedef gimple *gimple_ptr; +typedef const gimple *const_gimple_ptr; +#define gimple gimple_ptr +#define const_gimple const_gimple_ptr +#undef CONST_CAST_GIMPLE +#define CONST_CAST_GIMPLE(X) CONST_CAST(gimple, (X)) +#endif + +/* gimple related */ +static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree lhs, tree op1, tree op2 MEM_STAT_DECL) +{ + return gimple_build_assign(lhs, subcode, op1, op2 PASS_MEM_STAT); +} + +template <> +template <> +inline bool is_a_helper::test(const_gimple gs) +{ + return gs->code == GIMPLE_RETURN; +} + +static inline gasm *as_a_gasm(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gasm *as_a_const_gasm(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline gassign *as_a_gassign(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gassign *as_a_const_gassign(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline gcall *as_a_gcall(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gcall *as_a_const_gcall(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline gphi *as_a_gphi(gimple stmt) +{ + return as_a(stmt); +} + +static inline const gphi *as_a_const_gphi(const_gimple stmt) +{ + return as_a(stmt); +} + +static inline greturn *as_a_greturn(gimple stmt) +{ + return as_a(stmt); +} + +static inline const greturn *as_a_const_greturn(const_gimple stmt) +{ + return as_a(stmt); +} + +/* IPA/LTO related */ +#define ipa_ref_list_referring_iterate(L, I, P) \ + (L)->referring.iterate((I), &(P)) +#define ipa_ref_list_reference_iterate(L, I, P) \ + (L)->reference.iterate((I), &(P)) + +static inline cgraph_node_ptr ipa_ref_referring_node(struct ipa_ref *ref) +{ + return dyn_cast(ref->referring); +} + +static inline void ipa_remove_stmt_references(symtab_node *referring_node, gimple stmt) +{ + referring_node->remove_stmt_references(stmt); +} +#endif + +#if BUILDING_GCC_VERSION < 6000 +#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \ + get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, pvolatilep, keep_aligning) +#define gen_rtx_set(ARG0, ARG1) gen_rtx_SET(VOIDmode, (ARG0), (ARG1)) +#endif + +#if BUILDING_GCC_VERSION >= 6000 +#define gen_rtx_set(ARG0, ARG1) gen_rtx_SET((ARG0), (ARG1)) +#endif + +#ifdef __cplusplus +static inline void debug_tree(const_tree t) +{ + debug_tree(CONST_CAST_TREE(t)); +} + +static inline void debug_gimple_stmt(const_gimple s) +{ + debug_gimple_stmt(CONST_CAST_GIMPLE(s)); +} +#else +#define debug_tree(t) debug_tree(CONST_CAST_TREE(t)) +#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s)) +#endif + +#endif diff --git a/scripts/gcc-plugins/gcc-generate-gimple-pass.h b/scripts/gcc-plugins/gcc-generate-gimple-pass.h new file mode 100644 index 000000000000..526c3c79b68e --- /dev/null +++ b/scripts/gcc-plugins/gcc-generate-gimple-pass.h @@ -0,0 +1,175 @@ +/* + * Generator for GIMPLE pass related boilerplate code/data + * + * Supports gcc 4.5-6 + * + * Usage: + * + * 1. before inclusion define PASS_NAME + * 2. before inclusion define NO_* for unimplemented callbacks + * NO_GATE + * NO_EXECUTE + * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override + * the default 0 values + * 4. for convenience, all the above will be undefined after inclusion! + * 5. the only exported name is make_PASS_NAME_pass() to register with gcc + */ + +#ifndef PASS_NAME +#error at least PASS_NAME must be defined +#else +#define __GCC_PLUGIN_STRINGIFY(n) #n +#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n) +#define _GCC_PLUGIN_CONCAT2(x, y) x ## y +#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z + +#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data) +#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME) + +#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass) +#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME) + +#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME) + +#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass) +#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME) + +#ifdef NO_GATE +#define _GATE NULL +#define _HAS_GATE false +#else +#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate) +#define _GATE __GATE(PASS_NAME) +#define _HAS_GATE true +#endif + +#ifdef NO_EXECUTE +#define _EXECUTE NULL +#define _HAS_EXECUTE false +#else +#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute) +#define _EXECUTE __EXECUTE(PASS_NAME) +#define _HAS_EXECUTE true +#endif + +#ifndef PROPERTIES_REQUIRED +#define PROPERTIES_REQUIRED 0 +#endif + +#ifndef PROPERTIES_PROVIDED +#define PROPERTIES_PROVIDED 0 +#endif + +#ifndef PROPERTIES_DESTROYED +#define PROPERTIES_DESTROYED 0 +#endif + +#ifndef TODO_FLAGS_START +#define TODO_FLAGS_START 0 +#endif + +#ifndef TODO_FLAGS_FINISH +#define TODO_FLAGS_FINISH 0 +#endif + +#if BUILDING_GCC_VERSION >= 4009 +namespace { +static const pass_data _PASS_NAME_PASS_DATA = { +#else +static struct gimple_opt_pass _PASS_NAME_PASS = { + .pass = { +#endif + .type = GIMPLE_PASS, + .name = _PASS_NAME_NAME, +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif +#if BUILDING_GCC_VERSION >= 5000 +#elif BUILDING_GCC_VERSION == 4009 + .has_gate = _HAS_GATE, + .has_execute = _HAS_EXECUTE, +#else + .gate = _GATE, + .execute = _EXECUTE, + .sub = NULL, + .next = NULL, + .static_pass_number = 0, +#endif + .tv_id = TV_NONE, + .properties_required = PROPERTIES_REQUIRED, + .properties_provided = PROPERTIES_PROVIDED, + .properties_destroyed = PROPERTIES_DESTROYED, + .todo_flags_start = TODO_FLAGS_START, + .todo_flags_finish = TODO_FLAGS_FINISH, +#if BUILDING_GCC_VERSION < 4009 + } +#endif +}; + +#if BUILDING_GCC_VERSION >= 4009 +class _PASS_NAME_PASS : public gimple_opt_pass { +public: + _PASS_NAME_PASS() : gimple_opt_pass(_PASS_NAME_PASS_DATA, g) {} + +#ifndef NO_GATE +#if BUILDING_GCC_VERSION >= 5000 + virtual bool gate(function *) { return _GATE(); } +#else + virtual bool gate(void) { return _GATE(); } +#endif +#endif + + virtual opt_pass * clone () { return new _PASS_NAME_PASS(); } + +#ifndef NO_EXECUTE +#if BUILDING_GCC_VERSION >= 5000 + virtual unsigned int execute(function *) { return _EXECUTE(); } +#else + virtual unsigned int execute(void) { return _EXECUTE(); } +#endif +#endif +}; +} + +opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return new _PASS_NAME_PASS(); +} +#else +struct opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return &_PASS_NAME_PASS.pass; +} +#endif + +/* clean up user provided defines */ +#undef PASS_NAME +#undef NO_GATE +#undef NO_EXECUTE + +#undef PROPERTIES_DESTROYED +#undef PROPERTIES_PROVIDED +#undef PROPERTIES_REQUIRED +#undef TODO_FLAGS_FINISH +#undef TODO_FLAGS_START + +/* clean up generated defines */ +#undef _EXECUTE +#undef __EXECUTE +#undef _GATE +#undef __GATE +#undef _GCC_PLUGIN_CONCAT2 +#undef _GCC_PLUGIN_CONCAT3 +#undef _GCC_PLUGIN_STRINGIFY +#undef __GCC_PLUGIN_STRINGIFY +#undef _HAS_EXECUTE +#undef _HAS_GATE +#undef _MAKE_PASS_NAME_PASS +#undef __MAKE_PASS_NAME_PASS +#undef _PASS_NAME_NAME +#undef _PASS_NAME_PASS +#undef __PASS_NAME_PASS +#undef _PASS_NAME_PASS_DATA +#undef __PASS_NAME_PASS_DATA + +#endif /* PASS_NAME */ diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h new file mode 100644 index 000000000000..9bd926e072f0 --- /dev/null +++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h @@ -0,0 +1,289 @@ +/* + * Generator for IPA pass related boilerplate code/data + * + * Supports gcc 4.5-6 + * + * Usage: + * + * 1. before inclusion define PASS_NAME + * 2. before inclusion define NO_* for unimplemented callbacks + * NO_GENERATE_SUMMARY + * NO_READ_SUMMARY + * NO_WRITE_SUMMARY + * NO_READ_OPTIMIZATION_SUMMARY + * NO_WRITE_OPTIMIZATION_SUMMARY + * NO_STMT_FIXUP + * NO_FUNCTION_TRANSFORM + * NO_VARIABLE_TRANSFORM + * NO_GATE + * NO_EXECUTE + * 3. before inclusion define PROPERTIES_* and *TODO_FLAGS_* to override + * the default 0 values + * 4. for convenience, all the above will be undefined after inclusion! + * 5. the only exported name is make_PASS_NAME_pass() to register with gcc + */ + +#ifndef PASS_NAME +#error at least PASS_NAME must be defined +#else +#define __GCC_PLUGIN_STRINGIFY(n) #n +#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n) +#define _GCC_PLUGIN_CONCAT2(x, y) x ## y +#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z + +#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data) +#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME) + +#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass) +#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME) + +#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME) + +#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass) +#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME) + +#ifdef NO_GENERATE_SUMMARY +#define _GENERATE_SUMMARY NULL +#else +#define __GENERATE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _generate_summary) +#define _GENERATE_SUMMARY __GENERATE_SUMMARY(PASS_NAME) +#endif + +#ifdef NO_READ_SUMMARY +#define _READ_SUMMARY NULL +#else +#define __READ_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_summary) +#define _READ_SUMMARY __READ_SUMMARY(PASS_NAME) +#endif + +#ifdef NO_WRITE_SUMMARY +#define _WRITE_SUMMARY NULL +#else +#define __WRITE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_summary) +#define _WRITE_SUMMARY __WRITE_SUMMARY(PASS_NAME) +#endif + +#ifdef NO_READ_OPTIMIZATION_SUMMARY +#define _READ_OPTIMIZATION_SUMMARY NULL +#else +#define __READ_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_optimization_summary) +#define _READ_OPTIMIZATION_SUMMARY __READ_OPTIMIZATION_SUMMARY(PASS_NAME) +#endif + +#ifdef NO_WRITE_OPTIMIZATION_SUMMARY +#define _WRITE_OPTIMIZATION_SUMMARY NULL +#else +#define __WRITE_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_optimization_summary) +#define _WRITE_OPTIMIZATION_SUMMARY __WRITE_OPTIMIZATION_SUMMARY(PASS_NAME) +#endif + +#ifdef NO_STMT_FIXUP +#define _STMT_FIXUP NULL +#else +#define __STMT_FIXUP(n) _GCC_PLUGIN_CONCAT2(n, _stmt_fixup) +#define _STMT_FIXUP __STMT_FIXUP(PASS_NAME) +#endif + +#ifdef NO_FUNCTION_TRANSFORM +#define _FUNCTION_TRANSFORM NULL +#else +#define __FUNCTION_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _function_transform) +#define _FUNCTION_TRANSFORM __FUNCTION_TRANSFORM(PASS_NAME) +#endif + +#ifdef NO_VARIABLE_TRANSFORM +#define _VARIABLE_TRANSFORM NULL +#else +#define __VARIABLE_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _variable_transform) +#define _VARIABLE_TRANSFORM __VARIABLE_TRANSFORM(PASS_NAME) +#endif + +#ifdef NO_GATE +#define _GATE NULL +#define _HAS_GATE false +#else +#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate) +#define _GATE __GATE(PASS_NAME) +#define _HAS_GATE true +#endif + +#ifdef NO_EXECUTE +#define _EXECUTE NULL +#define _HAS_EXECUTE false +#else +#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute) +#define _EXECUTE __EXECUTE(PASS_NAME) +#define _HAS_EXECUTE true +#endif + +#ifndef PROPERTIES_REQUIRED +#define PROPERTIES_REQUIRED 0 +#endif + +#ifndef PROPERTIES_PROVIDED +#define PROPERTIES_PROVIDED 0 +#endif + +#ifndef PROPERTIES_DESTROYED +#define PROPERTIES_DESTROYED 0 +#endif + +#ifndef TODO_FLAGS_START +#define TODO_FLAGS_START 0 +#endif + +#ifndef TODO_FLAGS_FINISH +#define TODO_FLAGS_FINISH 0 +#endif + +#ifndef FUNCTION_TRANSFORM_TODO_FLAGS_START +#define FUNCTION_TRANSFORM_TODO_FLAGS_START 0 +#endif + +#if BUILDING_GCC_VERSION >= 4009 +namespace { +static const pass_data _PASS_NAME_PASS_DATA = { +#else +static struct ipa_opt_pass_d _PASS_NAME_PASS = { + .pass = { +#endif + .type = IPA_PASS, + .name = _PASS_NAME_NAME, +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif +#if BUILDING_GCC_VERSION >= 5000 +#elif BUILDING_GCC_VERSION == 4009 + .has_gate = _HAS_GATE, + .has_execute = _HAS_EXECUTE, +#else + .gate = _GATE, + .execute = _EXECUTE, + .sub = NULL, + .next = NULL, + .static_pass_number = 0, +#endif + .tv_id = TV_NONE, + .properties_required = PROPERTIES_REQUIRED, + .properties_provided = PROPERTIES_PROVIDED, + .properties_destroyed = PROPERTIES_DESTROYED, + .todo_flags_start = TODO_FLAGS_START, + .todo_flags_finish = TODO_FLAGS_FINISH, +#if BUILDING_GCC_VERSION < 4009 + }, + .generate_summary = _GENERATE_SUMMARY, + .write_summary = _WRITE_SUMMARY, + .read_summary = _READ_SUMMARY, +#if BUILDING_GCC_VERSION >= 4006 + .write_optimization_summary = _WRITE_OPTIMIZATION_SUMMARY, + .read_optimization_summary = _READ_OPTIMIZATION_SUMMARY, +#endif + .stmt_fixup = _STMT_FIXUP, + .function_transform_todo_flags_start = FUNCTION_TRANSFORM_TODO_FLAGS_START, + .function_transform = _FUNCTION_TRANSFORM, + .variable_transform = _VARIABLE_TRANSFORM, +#endif +}; + +#if BUILDING_GCC_VERSION >= 4009 +class _PASS_NAME_PASS : public ipa_opt_pass_d { +public: + _PASS_NAME_PASS() : ipa_opt_pass_d(_PASS_NAME_PASS_DATA, + g, + _GENERATE_SUMMARY, + _WRITE_SUMMARY, + _READ_SUMMARY, + _WRITE_OPTIMIZATION_SUMMARY, + _READ_OPTIMIZATION_SUMMARY, + _STMT_FIXUP, + FUNCTION_TRANSFORM_TODO_FLAGS_START, + _FUNCTION_TRANSFORM, + _VARIABLE_TRANSFORM) {} + +#ifndef NO_GATE +#if BUILDING_GCC_VERSION >= 5000 + virtual bool gate(function *) { return _GATE(); } +#else + virtual bool gate(void) { return _GATE(); } +#endif +#endif + + virtual opt_pass *clone() { return new _PASS_NAME_PASS(); } + +#ifndef NO_EXECUTE +#if BUILDING_GCC_VERSION >= 5000 + virtual unsigned int execute(function *) { return _EXECUTE(); } +#else + virtual unsigned int execute(void) { return _EXECUTE(); } +#endif +#endif +}; +} + +opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return new _PASS_NAME_PASS(); +} +#else +struct opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return &_PASS_NAME_PASS.pass; +} +#endif + +/* clean up user provided defines */ +#undef PASS_NAME +#undef NO_GENERATE_SUMMARY +#undef NO_WRITE_SUMMARY +#undef NO_READ_SUMMARY +#undef NO_WRITE_OPTIMIZATION_SUMMARY +#undef NO_READ_OPTIMIZATION_SUMMARY +#undef NO_STMT_FIXUP +#undef NO_FUNCTION_TRANSFORM +#undef NO_VARIABLE_TRANSFORM +#undef NO_GATE +#undef NO_EXECUTE + +#undef FUNCTION_TRANSFORM_TODO_FLAGS_START +#undef PROPERTIES_DESTROYED +#undef PROPERTIES_PROVIDED +#undef PROPERTIES_REQUIRED +#undef TODO_FLAGS_FINISH +#undef TODO_FLAGS_START + +/* clean up generated defines */ +#undef _EXECUTE +#undef __EXECUTE +#undef _FUNCTION_TRANSFORM +#undef __FUNCTION_TRANSFORM +#undef _GATE +#undef __GATE +#undef _GCC_PLUGIN_CONCAT2 +#undef _GCC_PLUGIN_CONCAT3 +#undef _GCC_PLUGIN_STRINGIFY +#undef __GCC_PLUGIN_STRINGIFY +#undef _GENERATE_SUMMARY +#undef __GENERATE_SUMMARY +#undef _HAS_EXECUTE +#undef _HAS_GATE +#undef _MAKE_PASS_NAME_PASS +#undef __MAKE_PASS_NAME_PASS +#undef _PASS_NAME_NAME +#undef _PASS_NAME_PASS +#undef __PASS_NAME_PASS +#undef _PASS_NAME_PASS_DATA +#undef __PASS_NAME_PASS_DATA +#undef _READ_OPTIMIZATION_SUMMARY +#undef __READ_OPTIMIZATION_SUMMARY +#undef _READ_SUMMARY +#undef __READ_SUMMARY +#undef _STMT_FIXUP +#undef __STMT_FIXUP +#undef _VARIABLE_TRANSFORM +#undef __VARIABLE_TRANSFORM +#undef _WRITE_OPTIMIZATION_SUMMARY +#undef __WRITE_OPTIMIZATION_SUMMARY +#undef _WRITE_SUMMARY +#undef __WRITE_SUMMARY + +#endif /* PASS_NAME */ diff --git a/scripts/gcc-plugins/gcc-generate-rtl-pass.h b/scripts/gcc-plugins/gcc-generate-rtl-pass.h new file mode 100644 index 000000000000..1dc67a5aeadf --- /dev/null +++ b/scripts/gcc-plugins/gcc-generate-rtl-pass.h @@ -0,0 +1,175 @@ +/* + * Generator for RTL pass related boilerplate code/data + * + * Supports gcc 4.5-6 + * + * Usage: + * + * 1. before inclusion define PASS_NAME + * 2. before inclusion define NO_* for unimplemented callbacks + * NO_GATE + * NO_EXECUTE + * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override + * the default 0 values + * 4. for convenience, all the above will be undefined after inclusion! + * 5. the only exported name is make_PASS_NAME_pass() to register with gcc + */ + +#ifndef PASS_NAME +#error at least PASS_NAME must be defined +#else +#define __GCC_PLUGIN_STRINGIFY(n) #n +#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n) +#define _GCC_PLUGIN_CONCAT2(x, y) x ## y +#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z + +#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data) +#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME) + +#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass) +#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME) + +#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME) + +#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass) +#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME) + +#ifdef NO_GATE +#define _GATE NULL +#define _HAS_GATE false +#else +#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate) +#define _GATE __GATE(PASS_NAME) +#define _HAS_GATE true +#endif + +#ifdef NO_EXECUTE +#define _EXECUTE NULL +#define _HAS_EXECUTE false +#else +#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute) +#define _EXECUTE __EXECUTE(PASS_NAME) +#define _HAS_EXECUTE true +#endif + +#ifndef PROPERTIES_REQUIRED +#define PROPERTIES_REQUIRED 0 +#endif + +#ifndef PROPERTIES_PROVIDED +#define PROPERTIES_PROVIDED 0 +#endif + +#ifndef PROPERTIES_DESTROYED +#define PROPERTIES_DESTROYED 0 +#endif + +#ifndef TODO_FLAGS_START +#define TODO_FLAGS_START 0 +#endif + +#ifndef TODO_FLAGS_FINISH +#define TODO_FLAGS_FINISH 0 +#endif + +#if BUILDING_GCC_VERSION >= 4009 +namespace { +static const pass_data _PASS_NAME_PASS_DATA = { +#else +static struct rtl_opt_pass _PASS_NAME_PASS = { + .pass = { +#endif + .type = RTL_PASS, + .name = _PASS_NAME_NAME, +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif +#if BUILDING_GCC_VERSION >= 5000 +#elif BUILDING_GCC_VERSION == 4009 + .has_gate = _HAS_GATE, + .has_execute = _HAS_EXECUTE, +#else + .gate = _GATE, + .execute = _EXECUTE, + .sub = NULL, + .next = NULL, + .static_pass_number = 0, +#endif + .tv_id = TV_NONE, + .properties_required = PROPERTIES_REQUIRED, + .properties_provided = PROPERTIES_PROVIDED, + .properties_destroyed = PROPERTIES_DESTROYED, + .todo_flags_start = TODO_FLAGS_START, + .todo_flags_finish = TODO_FLAGS_FINISH, +#if BUILDING_GCC_VERSION < 4009 + } +#endif +}; + +#if BUILDING_GCC_VERSION >= 4009 +class _PASS_NAME_PASS : public rtl_opt_pass { +public: + _PASS_NAME_PASS() : rtl_opt_pass(_PASS_NAME_PASS_DATA, g) {} + +#ifndef NO_GATE +#if BUILDING_GCC_VERSION >= 5000 + virtual bool gate(function *) { return _GATE(); } +#else + virtual bool gate(void) { return _GATE(); } +#endif +#endif + + virtual opt_pass *clone() { return new _PASS_NAME_PASS(); } + +#ifndef NO_EXECUTE +#if BUILDING_GCC_VERSION >= 5000 + virtual unsigned int execute(function *) { return _EXECUTE(); } +#else + virtual unsigned int execute(void) { return _EXECUTE(); } +#endif +#endif +}; +} + +opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return new _PASS_NAME_PASS(); +} +#else +struct opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return &_PASS_NAME_PASS.pass; +} +#endif + +/* clean up user provided defines */ +#undef PASS_NAME +#undef NO_GATE +#undef NO_EXECUTE + +#undef PROPERTIES_DESTROYED +#undef PROPERTIES_PROVIDED +#undef PROPERTIES_REQUIRED +#undef TODO_FLAGS_FINISH +#undef TODO_FLAGS_START + +/* clean up generated defines */ +#undef _EXECUTE +#undef __EXECUTE +#undef _GATE +#undef __GATE +#undef _GCC_PLUGIN_CONCAT2 +#undef _GCC_PLUGIN_CONCAT3 +#undef _GCC_PLUGIN_STRINGIFY +#undef __GCC_PLUGIN_STRINGIFY +#undef _HAS_EXECUTE +#undef _HAS_GATE +#undef _MAKE_PASS_NAME_PASS +#undef __MAKE_PASS_NAME_PASS +#undef _PASS_NAME_NAME +#undef _PASS_NAME_PASS +#undef __PASS_NAME_PASS +#undef _PASS_NAME_PASS_DATA +#undef __PASS_NAME_PASS_DATA + +#endif /* PASS_NAME */ diff --git a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h new file mode 100644 index 000000000000..a27e2b36afaa --- /dev/null +++ b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h @@ -0,0 +1,175 @@ +/* + * Generator for SIMPLE_IPA pass related boilerplate code/data + * + * Supports gcc 4.5-6 + * + * Usage: + * + * 1. before inclusion define PASS_NAME + * 2. before inclusion define NO_* for unimplemented callbacks + * NO_GATE + * NO_EXECUTE + * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override + * the default 0 values + * 4. for convenience, all the above will be undefined after inclusion! + * 5. the only exported name is make_PASS_NAME_pass() to register with gcc + */ + +#ifndef PASS_NAME +#error at least PASS_NAME must be defined +#else +#define __GCC_PLUGIN_STRINGIFY(n) #n +#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n) +#define _GCC_PLUGIN_CONCAT2(x, y) x ## y +#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z + +#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data) +#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME) + +#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass) +#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME) + +#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME) + +#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass) +#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME) + +#ifdef NO_GATE +#define _GATE NULL +#define _HAS_GATE false +#else +#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate) +#define _GATE __GATE(PASS_NAME) +#define _HAS_GATE true +#endif + +#ifdef NO_EXECUTE +#define _EXECUTE NULL +#define _HAS_EXECUTE false +#else +#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute) +#define _EXECUTE __EXECUTE(PASS_NAME) +#define _HAS_EXECUTE true +#endif + +#ifndef PROPERTIES_REQUIRED +#define PROPERTIES_REQUIRED 0 +#endif + +#ifndef PROPERTIES_PROVIDED +#define PROPERTIES_PROVIDED 0 +#endif + +#ifndef PROPERTIES_DESTROYED +#define PROPERTIES_DESTROYED 0 +#endif + +#ifndef TODO_FLAGS_START +#define TODO_FLAGS_START 0 +#endif + +#ifndef TODO_FLAGS_FINISH +#define TODO_FLAGS_FINISH 0 +#endif + +#if BUILDING_GCC_VERSION >= 4009 +namespace { +static const pass_data _PASS_NAME_PASS_DATA = { +#else +static struct simple_ipa_opt_pass _PASS_NAME_PASS = { + .pass = { +#endif + .type = SIMPLE_IPA_PASS, + .name = _PASS_NAME_NAME, +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif +#if BUILDING_GCC_VERSION >= 5000 +#elif BUILDING_GCC_VERSION == 4009 + .has_gate = _HAS_GATE, + .has_execute = _HAS_EXECUTE, +#else + .gate = _GATE, + .execute = _EXECUTE, + .sub = NULL, + .next = NULL, + .static_pass_number = 0, +#endif + .tv_id = TV_NONE, + .properties_required = PROPERTIES_REQUIRED, + .properties_provided = PROPERTIES_PROVIDED, + .properties_destroyed = PROPERTIES_DESTROYED, + .todo_flags_start = TODO_FLAGS_START, + .todo_flags_finish = TODO_FLAGS_FINISH, +#if BUILDING_GCC_VERSION < 4009 + } +#endif +}; + +#if BUILDING_GCC_VERSION >= 4009 +class _PASS_NAME_PASS : public simple_ipa_opt_pass { +public: + _PASS_NAME_PASS() : simple_ipa_opt_pass(_PASS_NAME_PASS_DATA, g) {} + +#ifndef NO_GATE +#if BUILDING_GCC_VERSION >= 5000 + virtual bool gate(function *) { return _GATE(); } +#else + virtual bool gate(void) { return _GATE(); } +#endif +#endif + + virtual opt_pass *clone() { return new _PASS_NAME_PASS(); } + +#ifndef NO_EXECUTE +#if BUILDING_GCC_VERSION >= 5000 + virtual unsigned int execute(function *) { return _EXECUTE(); } +#else + virtual unsigned int execute(void) { return _EXECUTE(); } +#endif +#endif +}; +} + +opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return new _PASS_NAME_PASS(); +} +#else +struct opt_pass *_MAKE_PASS_NAME_PASS(void) +{ + return &_PASS_NAME_PASS.pass; +} +#endif + +/* clean up user provided defines */ +#undef PASS_NAME +#undef NO_GATE +#undef NO_EXECUTE + +#undef PROPERTIES_DESTROYED +#undef PROPERTIES_PROVIDED +#undef PROPERTIES_REQUIRED +#undef TODO_FLAGS_FINISH +#undef TODO_FLAGS_START + +/* clean up generated defines */ +#undef _EXECUTE +#undef __EXECUTE +#undef _GATE +#undef __GATE +#undef _GCC_PLUGIN_CONCAT2 +#undef _GCC_PLUGIN_CONCAT3 +#undef _GCC_PLUGIN_STRINGIFY +#undef __GCC_PLUGIN_STRINGIFY +#undef _HAS_EXECUTE +#undef _HAS_GATE +#undef _MAKE_PASS_NAME_PASS +#undef __MAKE_PASS_NAME_PASS +#undef _PASS_NAME_NAME +#undef _PASS_NAME_PASS +#undef __PASS_NAME_PASS +#undef _PASS_NAME_PASS_DATA +#undef __PASS_NAME_PASS_DATA + +#endif /* PASS_NAME */ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index f0f6d9d75435..4f727eb5ec43 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -180,7 +180,7 @@ else fi; # final build of init/ -${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init +${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}" kallsymso="" kallsyms_vmlinux="" diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 86e56fef7473..4d4418a8d54d 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -329,6 +329,7 @@ fi (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" (cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles" +(cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles" destdir=$kernel_headers_dir/usr/src/linux-headers-$version mkdir -p "$destdir" (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) -- cgit v1.3-14-g43fede From 2f4cd8d0a5193bd205f0bf77648763c5f982ae4a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 7 Jun 2016 13:05:44 +0200 Subject: dt-bindings: Add root properties for Raspberry Pi 3 Signed-off-by: Eric Anholt Acked-by: Stephen Warren Acked-by: Rob Herring --- Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt index 11d3056dc2bd..6ffe08778465 100644 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt @@ -30,6 +30,10 @@ Raspberry Pi 2 Model B Required root node properties: compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; +Raspberry Pi 3 Model B +Required root node properties: +compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; + Raspberry Pi Compute Module Required root node properties: compatible = "raspberrypi,compute-module", "brcm,bcm2835"; -- cgit v1.3-14-g43fede From edb09eb17ed89eaa82a52dd306beac93e292b485 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 6 Jun 2016 09:37:16 -0700 Subject: net: sched: do not acquire qdisc spinlock in qdisc/class stats dump Large tc dumps (tc -s {qdisc|class} sh dev ethX) done by Google BwE host agent [1] are problematic at scale : For each qdisc/class found in the dump, we currently lock the root qdisc spinlock in order to get stats. Sampling stats every 5 seconds from thousands of HTB classes is a challenge when the root qdisc spinlock is under high pressure. Not only the dumps take time, they also slow down the fast path (queue/dequeue packets) by 10 % to 20 % in some cases. An audit of existing qdiscs showed that sch_fq_codel is the only qdisc that might need the qdisc lock in fq_codel_dump_stats() and fq_codel_dump_class_stats() In v2 of this patch, I now use the Qdisc running seqcount to provide consistent reads of packets/bytes counters, regardless of 32/64 bit arches. I also changed rate estimators to use the same infrastructure so that they no longer need to lock root qdisc lock. [1] http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43838.pdf Signed-off-by: Eric Dumazet Cc: Cong Wang Cc: Jamal Hadi Salim Cc: John Fastabend Cc: Kevin Athey Cc: Xiaotian Pei Signed-off-by: David S. Miller --- Documentation/networking/gen_stats.txt | 2 +- include/net/gen_stats.h | 12 ++++++++---- include/net/sch_generic.h | 8 ++++++++ net/core/gen_estimator.c | 24 ++++++++++++++++-------- net/core/gen_stats.c | 34 +++++++++++++++++++++++----------- net/netfilter/xt_RATEEST.c | 2 +- net/sched/act_api.c | 4 ++-- net/sched/act_police.c | 3 ++- net/sched/sch_api.c | 21 +++++++++++---------- net/sched/sch_atm.c | 3 ++- net/sched/sch_cbq.c | 9 ++++++--- net/sched/sch_drr.c | 9 ++++++--- net/sched/sch_fq_codel.c | 15 +++++++++++---- net/sched/sch_hfsc.c | 10 +++++----- net/sched/sch_htb.c | 11 ++++++----- net/sched/sch_mq.c | 2 +- net/sched/sch_mqprio.c | 11 +++++++---- net/sched/sch_multiq.c | 3 ++- net/sched/sch_prio.c | 3 ++- net/sched/sch_qfq.c | 9 ++++++--- 20 files changed, 126 insertions(+), 69 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/gen_stats.txt b/Documentation/networking/gen_stats.txt index ff630a87b511..179b18ce45ff 100644 --- a/Documentation/networking/gen_stats.txt +++ b/Documentation/networking/gen_stats.txt @@ -21,7 +21,7 @@ struct mystruct { ... }; -Update statistics: +Update statistics, in dequeue() methods only, (while owning qdisc->running) mystruct->tstats.packet++; mystruct->qstats.backlog += skb->pkt_len; diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h index 610cd397890e..231e121cc7d9 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h @@ -33,10 +33,12 @@ int gnet_stats_start_copy_compat(struct sk_buff *skb, int type, spinlock_t *lock, struct gnet_dump *d, int padattr); -int gnet_stats_copy_basic(struct gnet_dump *d, +int gnet_stats_copy_basic(const seqcount_t *running, + struct gnet_dump *d, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b); -void __gnet_stats_copy_basic(struct gnet_stats_basic_packed *bstats, +void __gnet_stats_copy_basic(const seqcount_t *running, + struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b); int gnet_stats_copy_rate_est(struct gnet_dump *d, @@ -52,13 +54,15 @@ int gnet_stats_finish_copy(struct gnet_dump *d); int gen_new_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct gnet_stats_rate_est64 *rate_est, - spinlock_t *stats_lock, struct nlattr *opt); + spinlock_t *stats_lock, + seqcount_t *running, struct nlattr *opt); void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est64 *rate_est); int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct gnet_stats_rate_est64 *rate_est, - spinlock_t *stats_lock, struct nlattr *opt); + spinlock_t *stats_lock, + seqcount_t *running, struct nlattr *opt); bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, const struct gnet_stats_rate_est64 *rate_est); #endif diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index bff8d895ef8a..c4f5749342ec 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -314,6 +314,14 @@ static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc) return qdisc_lock(root); } +static inline seqcount_t *qdisc_root_sleeping_running(const struct Qdisc *qdisc) +{ + struct Qdisc *root = qdisc_root_sleeping(qdisc); + + ASSERT_RTNL(); + return &root->running; +} + static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc) { return qdisc->dev_queue->dev; diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 4573d81093fe..cad8e791f28e 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -84,6 +84,7 @@ struct gen_estimator struct gnet_stats_basic_packed *bstats; struct gnet_stats_rate_est64 *rate_est; spinlock_t *stats_lock; + seqcount_t *running; int ewma_log; u32 last_packets; unsigned long avpps; @@ -121,26 +122,28 @@ static void est_timer(unsigned long arg) unsigned long rate; u64 brate; - spin_lock(e->stats_lock); + if (e->stats_lock) + spin_lock(e->stats_lock); read_lock(&est_lock); if (e->bstats == NULL) goto skip; - __gnet_stats_copy_basic(&b, e->cpu_bstats, e->bstats); + __gnet_stats_copy_basic(e->running, &b, e->cpu_bstats, e->bstats); brate = (b.bytes - e->last_bytes)<<(7 - idx); e->last_bytes = b.bytes; e->avbps += (brate >> e->ewma_log) - (e->avbps >> e->ewma_log); - e->rate_est->bps = (e->avbps+0xF)>>5; + WRITE_ONCE(e->rate_est->bps, (e->avbps + 0xF) >> 5); rate = b.packets - e->last_packets; rate <<= (7 - idx); e->last_packets = b.packets; e->avpps += (rate >> e->ewma_log) - (e->avpps >> e->ewma_log); - e->rate_est->pps = (e->avpps + 0xF) >> 5; + WRITE_ONCE(e->rate_est->pps, (e->avpps + 0xF) >> 5); skip: read_unlock(&est_lock); - spin_unlock(e->stats_lock); + if (e->stats_lock) + spin_unlock(e->stats_lock); } if (!list_empty(&elist[idx].list)) @@ -194,6 +197,7 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats * @cpu_bstats: bstats per cpu * @rate_est: rate estimator statistics * @stats_lock: statistics lock + * @running: qdisc running seqcount * @opt: rate estimator configuration TLV * * Creates a new rate estimator with &bstats as source and &rate_est @@ -209,6 +213,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct gnet_stats_rate_est64 *rate_est, spinlock_t *stats_lock, + seqcount_t *running, struct nlattr *opt) { struct gen_estimator *est; @@ -226,12 +231,13 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, if (est == NULL) return -ENOBUFS; - __gnet_stats_copy_basic(&b, cpu_bstats, bstats); + __gnet_stats_copy_basic(running, &b, cpu_bstats, bstats); idx = parm->interval + 2; est->bstats = bstats; est->rate_est = rate_est; est->stats_lock = stats_lock; + est->running = running; est->ewma_log = parm->ewma_log; est->last_bytes = b.bytes; est->avbps = rate_est->bps<<5; @@ -291,6 +297,7 @@ EXPORT_SYMBOL(gen_kill_estimator); * @cpu_bstats: bstats per cpu * @rate_est: rate estimator statistics * @stats_lock: statistics lock + * @running: qdisc running seqcount (might be NULL) * @opt: rate estimator configuration TLV * * Replaces the configuration of a rate estimator by calling @@ -301,10 +308,11 @@ EXPORT_SYMBOL(gen_kill_estimator); int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu_bstats, struct gnet_stats_rate_est64 *rate_est, - spinlock_t *stats_lock, struct nlattr *opt) + spinlock_t *stats_lock, + seqcount_t *running, struct nlattr *opt) { gen_kill_estimator(bstats, rate_est); - return gen_new_estimator(bstats, cpu_bstats, rate_est, stats_lock, opt); + return gen_new_estimator(bstats, cpu_bstats, rate_est, stats_lock, running, opt); } EXPORT_SYMBOL(gen_replace_estimator); diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index f96ee8b9478d..d9c210caff32 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c @@ -32,10 +32,11 @@ gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size, int padattr) return 0; nla_put_failure: + if (d->lock) + spin_unlock_bh(d->lock); kfree(d->xstats); d->xstats = NULL; d->xstats_len = 0; - spin_unlock_bh(d->lock); return -1; } @@ -65,15 +66,16 @@ gnet_stats_start_copy_compat(struct sk_buff *skb, int type, int tc_stats_type, { memset(d, 0, sizeof(*d)); - spin_lock_bh(lock); - d->lock = lock; if (type) d->tail = (struct nlattr *)skb_tail_pointer(skb); d->skb = skb; d->compat_tc_stats = tc_stats_type; d->compat_xstats = xstats_type; d->padattr = padattr; - + if (lock) { + d->lock = lock; + spin_lock_bh(lock); + } if (d->tail) return gnet_stats_copy(d, type, NULL, 0, padattr); @@ -126,16 +128,23 @@ __gnet_stats_copy_basic_cpu(struct gnet_stats_basic_packed *bstats, } void -__gnet_stats_copy_basic(struct gnet_stats_basic_packed *bstats, +__gnet_stats_copy_basic(const seqcount_t *running, + struct gnet_stats_basic_packed *bstats, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b) { + unsigned int seq; + if (cpu) { __gnet_stats_copy_basic_cpu(bstats, cpu); - } else { + return; + } + do { + if (running) + seq = read_seqcount_begin(running); bstats->bytes = b->bytes; bstats->packets = b->packets; - } + } while (running && read_seqcount_retry(running, seq)); } EXPORT_SYMBOL(__gnet_stats_copy_basic); @@ -152,13 +161,14 @@ EXPORT_SYMBOL(__gnet_stats_copy_basic); * if the room in the socket buffer was not sufficient. */ int -gnet_stats_copy_basic(struct gnet_dump *d, +gnet_stats_copy_basic(const seqcount_t *running, + struct gnet_dump *d, struct gnet_stats_basic_cpu __percpu *cpu, struct gnet_stats_basic_packed *b) { struct gnet_stats_basic_packed bstats = {0}; - __gnet_stats_copy_basic(&bstats, cpu, b); + __gnet_stats_copy_basic(running, &bstats, cpu, b); if (d->compat_tc_stats) { d->tc_stats.bytes = bstats.bytes; @@ -328,8 +338,9 @@ gnet_stats_copy_app(struct gnet_dump *d, void *st, int len) return 0; err_out: + if (d->lock) + spin_unlock_bh(d->lock); d->xstats_len = 0; - spin_unlock_bh(d->lock); return -1; } EXPORT_SYMBOL(gnet_stats_copy_app); @@ -363,10 +374,11 @@ gnet_stats_finish_copy(struct gnet_dump *d) return -1; } + if (d->lock) + spin_unlock_bh(d->lock); kfree(d->xstats); d->xstats = NULL; d->xstats_len = 0; - spin_unlock_bh(d->lock); return 0; } EXPORT_SYMBOL(gnet_stats_finish_copy); diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 604df6fae6fc..515131f9e021 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c @@ -137,7 +137,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) cfg.est.ewma_log = info->ewma_log; ret = gen_new_estimator(&est->bstats, NULL, &est->rstats, - &est->lock, &cfg.opt); + &est->lock, NULL, &cfg.opt); if (ret < 0) goto err2; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 719bc2e85852..b6db56ec8117 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -287,7 +287,7 @@ err2: if (est) { err = gen_new_estimator(&p->tcfc_bstats, p->cpu_bstats, &p->tcfc_rate_est, - &p->tcfc_lock, est); + &p->tcfc_lock, NULL, est); if (err) { free_percpu(p->cpu_qstats); goto err2; @@ -671,7 +671,7 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, if (err < 0) goto errout; - if (gnet_stats_copy_basic(&d, p->cpu_bstats, &p->tcfc_bstats) < 0 || + if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfc_bstats) < 0 || gnet_stats_copy_rate_est(&d, &p->tcfc_bstats, &p->tcfc_rate_est) < 0 || gnet_stats_copy_queue(&d, p->cpu_qstats, diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 820b11686f85..bcb31142556b 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -185,7 +185,8 @@ override: if (est) { err = gen_replace_estimator(&police->tcf_bstats, NULL, &police->tcf_rate_est, - &police->tcf_lock, est); + &police->tcf_lock, + NULL, est); if (err) goto failure_unlock; } else if (tb[TCA_POLICE_AVRATE] && diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index ddf047df5361..d4a8bbfcc953 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -982,7 +982,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, rcu_assign_pointer(sch->stab, stab); } if (tca[TCA_RATE]) { - spinlock_t *root_lock; + seqcount_t *running; err = -EOPNOTSUPP; if (sch->flags & TCQ_F_MQROOT) @@ -991,14 +991,15 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, if ((sch->parent != TC_H_ROOT) && !(sch->flags & TCQ_F_INGRESS) && (!p || !(p->flags & TCQ_F_MQROOT))) - root_lock = qdisc_root_sleeping_lock(sch); + running = qdisc_root_sleeping_running(sch); else - root_lock = qdisc_lock(sch); + running = &sch->running; err = gen_new_estimator(&sch->bstats, sch->cpu_bstats, &sch->rate_est, - root_lock, + NULL, + running, tca[TCA_RATE]); if (err) goto err_out4; @@ -1061,7 +1062,8 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca) gen_replace_estimator(&sch->bstats, sch->cpu_bstats, &sch->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); } out: @@ -1369,8 +1371,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, goto nla_put_failure; if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, - qdisc_root_sleeping_lock(q), &d, - TCA_PAD) < 0) + NULL, &d, TCA_PAD) < 0) goto nla_put_failure; if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) @@ -1381,7 +1382,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, cpu_qstats = q->cpu_qstats; } - if (gnet_stats_copy_basic(&d, cpu_bstats, &q->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(q), + &d, cpu_bstats, &q->bstats) < 0 || gnet_stats_copy_rate_est(&d, &q->bstats, &q->rate_est) < 0 || gnet_stats_copy_queue(&d, cpu_qstats, &q->qstats, qlen) < 0) goto nla_put_failure; @@ -1684,8 +1686,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, goto nla_put_failure; if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, - qdisc_root_sleeping_lock(q), &d, - TCA_PAD) < 0) + NULL, &d, TCA_PAD) < 0) goto nla_put_failure; if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 1911af3ca7c0..34f8f79e56d5 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -637,7 +637,8 @@ atm_tc_dump_class_stats(struct Qdisc *sch, unsigned long arg, { struct atm_flow_data *flow = (struct atm_flow_data *)arg; - if (gnet_stats_copy_basic(d, NULL, &flow->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &flow->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &flow->qstats, flow->q->q.qlen) < 0) return -1; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index baafddf229ce..1b8128fb845d 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1600,7 +1600,8 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg, if (cl->undertime != PSCHED_PASTPERFECT) cl->xstats.undertime = cl->undertime - q->now; - if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 || gnet_stats_copy_queue(d, NULL, &cl->qstats, cl->q->q.qlen) < 0) return -1; @@ -1755,7 +1756,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) { qdisc_put_rtab(rtab); @@ -1848,7 +1850,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t if (tca[TCA_RATE]) { err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) { kfree(cl); diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index a63e879e8975..1b7e1a27773d 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -91,7 +91,8 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) return err; @@ -119,7 +120,8 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) { qdisc_destroy(cl->qdisc); @@ -279,7 +281,8 @@ static int drr_dump_class_stats(struct Qdisc *sch, unsigned long arg, if (qlen) xstats.deficit = cl->deficit; - if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 || gnet_stats_copy_queue(d, NULL, &cl->qdisc->qstats, qlen) < 0) return -1; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 6883a8971562..1daa54237f4e 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -566,11 +566,13 @@ static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) st.qdisc_stats.memory_usage = q->memory_usage; st.qdisc_stats.drop_overmemory = q->drop_overmemory; + sch_tree_lock(sch); list_for_each(pos, &q->new_flows) st.qdisc_stats.new_flows_len++; list_for_each(pos, &q->old_flows) st.qdisc_stats.old_flows_len++; + sch_tree_unlock(sch); return gnet_stats_copy_app(d, &st, sizeof(st)); } @@ -624,7 +626,7 @@ static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl, if (idx < q->flows_cnt) { const struct fq_codel_flow *flow = &q->flows[idx]; - const struct sk_buff *skb = flow->head; + const struct sk_buff *skb; memset(&xstats, 0, sizeof(xstats)); xstats.type = TCA_FQ_CODEL_XSTATS_CLASS; @@ -642,9 +644,14 @@ static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl, codel_time_to_us(delta) : -codel_time_to_us(-delta); } - while (skb) { - qs.qlen++; - skb = skb->next; + if (flow->head) { + sch_tree_lock(sch); + skb = flow->head; + while (skb) { + qs.qlen++; + skb = skb->next; + } + sch_tree_unlock(sch); } qs.backlog = q->backlogs[idx]; qs.drops = flow->dropped; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index d783d7cc3348..74813dd49053 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1015,11 +1015,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cur_time = psched_get_time(); if (tca[TCA_RATE]) { - spinlock_t *lock = qdisc_root_sleeping_lock(sch); - err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, - lock, + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) return err; @@ -1068,7 +1067,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tca[TCA_RATE]) { err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) { kfree(cl); @@ -1373,7 +1373,7 @@ hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg, xstats.work = cl->cl_total; xstats.rtwork = cl->cl_cumul; - if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d, NULL, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 || gnet_stats_copy_queue(d, NULL, &cl->qstats, cl->qdisc->q.qlen) < 0) return -1; diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index d4b4218af6b1..2b057649f24b 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1141,7 +1141,8 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d) cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens); cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens); - if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 || gnet_stats_copy_queue(d, NULL, &cl->qstats, qlen) < 0) return -1; @@ -1395,7 +1396,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, if (htb_rate_est || tca[TCA_RATE]) { err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE] ? : &est.nla); if (err) { kfree(cl); @@ -1457,11 +1459,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, parent->children++; } else { if (tca[TCA_RATE]) { - spinlock_t *lock = qdisc_root_sleeping_lock(sch); - err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, - lock, + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) return err; diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index 56a77b878eb3..b9439827c172 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -199,7 +199,7 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct netdev_queue *dev_queue = mq_queue_get(sch, cl); sch = dev_queue->qdisc_sleeping; - if (gnet_stats_copy_basic(d, NULL, &sch->bstats) < 0 || + if (gnet_stats_copy_basic(&sch->running, d, NULL, &sch->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &sch->qstats, sch->q.qlen) < 0) return -1; return 0; diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index b8002ce3d010..549c66359924 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -342,7 +342,8 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl, * hold here is the look on dev_queue->qdisc_sleeping * also acquired below. */ - spin_unlock_bh(d->lock); + if (d->lock) + spin_unlock_bh(d->lock); for (i = tc.offset; i < tc.offset + tc.count; i++) { struct netdev_queue *q = netdev_get_tx_queue(dev, i); @@ -359,15 +360,17 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl, spin_unlock_bh(qdisc_lock(qdisc)); } /* Reclaim root sleeping lock before completing stats */ - spin_lock_bh(d->lock); - if (gnet_stats_copy_basic(d, NULL, &bstats) < 0 || + if (d->lock) + spin_lock_bh(d->lock); + if (gnet_stats_copy_basic(NULL, d, NULL, &bstats) < 0 || gnet_stats_copy_queue(d, NULL, &qstats, qlen) < 0) return -1; } else { struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl); sch = dev_queue->qdisc_sleeping; - if (gnet_stats_copy_basic(d, NULL, &sch->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &sch->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &sch->qstats, sch->q.qlen) < 0) return -1; diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index bcdd54bb101c..21e69d2e8347 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -356,7 +356,8 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct Qdisc *cl_q; cl_q = q->queues[cl - 1]; - if (gnet_stats_copy_basic(d, NULL, &cl_q->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &cl_q->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0) return -1; diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index fee1b15506b2..06eca7060683 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -319,7 +319,8 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct Qdisc *cl_q; cl_q = q->queues[cl - 1]; - if (gnet_stats_copy_basic(d, NULL, &cl_q->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &cl_q->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0) return -1; diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 8d2d8d953432..85d41979d825 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -460,7 +460,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) return err; @@ -486,7 +487,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tca[TCA_RATE]) { err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est, - qdisc_root_sleeping_lock(sch), + NULL, + qdisc_root_sleeping_running(sch), tca[TCA_RATE]); if (err) goto destroy_class; @@ -663,7 +665,8 @@ static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg, xstats.weight = cl->agg->class_weight; xstats.lmax = cl->agg->lmax; - if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), + d, NULL, &cl->bstats) < 0 || gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 || gnet_stats_copy_queue(d, NULL, &cl->qdisc->qstats, cl->qdisc->q.qlen) < 0) -- cgit v1.3-14-g43fede From 7150bc9b4d43471fa37b26f5839892d4cf1fe09b Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Wed, 8 Jun 2016 12:15:10 +0800 Subject: usb: ohci-at91: Forcibly suspend ports while USB suspend In order to the save power consumption, as a workaround, suspend forcibly the USB PORTA/B/C via set the SUSPEND_A/B/C bits of OHCI Interrupt Configuration Register in the SFRs while OHCI USB suspend. This suspend operation must be done before the USB clock is disabled, resume after the USB clock is enabled. Signed-off-by: Wenyou Yang Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/atmel-usb.txt | 6 +- drivers/usb/host/ohci-at91.c | 80 +++++++++++++++++++++- include/soc/at91/at91_sfr.h | 29 ++++++++ 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 include/soc/at91/at91_sfr.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt index 5883b73ea1b5..888deaa8a4ca 100644 --- a/Documentation/devicetree/bindings/usb/atmel-usb.txt +++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt @@ -3,8 +3,10 @@ Atmel SOC USB controllers OHCI Required properties: - - compatible: Should be "atmel,at91rm9200-ohci" for USB controllers - used in host mode. + - compatible: Should be one of the following + "atmel,at91rm9200-ohci" for USB controllers used in host mode. + "atmel,sama5d2-ohci" for USB controllers used in host mode + on SAMA5D2 which can force to suspend. - reg: Address and length of the register set for the device - interrupts: Should contain ehci interrupt - clocks: Should reference the peripheral, host and system clocks diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index d177372bb357..54e8feb8a964 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -21,8 +21,11 @@ #include #include #include +#include +#include #include #include +#include #include "ohci.h" @@ -45,12 +48,18 @@ struct at91_usbh_data { u8 overcurrent_changed[AT91_MAX_USBH_PORTS]; }; +struct ohci_at91_caps { + bool suspend_ctrl; +}; + struct ohci_at91_priv { struct clk *iclk; struct clk *fclk; struct clk *hclk; bool clocked; bool wakeup; /* Saved wake-up state for resume */ + const struct ohci_at91_caps *caps; + struct regmap *sfr_regmap; }; /* interface and function clocks; sometimes also an AHB clock */ @@ -132,6 +141,17 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ +struct regmap *at91_dt_syscon_sfr(void) +{ + struct regmap *regmap; + + regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); + if (IS_ERR(regmap)) + regmap = NULL; + + return regmap; +} + static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ @@ -197,6 +217,17 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, goto err; } + ohci_at91->caps = (const struct ohci_at91_caps *) + of_device_get_match_data(&pdev->dev); + if (!ohci_at91->caps) + return -ENODEV; + + if (ohci_at91->caps->suspend_ctrl) { + ohci_at91->sfr_regmap = at91_dt_syscon_sfr(); + if (!ohci_at91->sfr_regmap) + dev_warn(dev, "failed to find sfr node\n"); + } + board = hcd->self.controller->platform_data; ohci = hcd_to_ohci(hcd); ohci->num_ports = board->ports; @@ -440,8 +471,17 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) return IRQ_HANDLED; } +static const struct ohci_at91_caps at91rm9200_caps = { + .suspend_ctrl = false, +}; + +static const struct ohci_at91_caps sama5d2_caps = { + .suspend_ctrl = true, +}; + static const struct of_device_id at91_ohci_dt_ids[] = { - { .compatible = "atmel,at91rm9200-ohci" }, + { .compatible = "atmel,at91rm9200-ohci", .data = &at91rm9200_caps }, + { .compatible = "atmel,sama5d2-ohci", .data = &sama5d2_caps }, { /* sentinel */ } }; @@ -581,6 +621,38 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) return 0; } +static int ohci_at91_port_ctrl(struct regmap *regmap, bool enable) +{ + u32 regval; + int ret; + + if (!regmap) + return -EINVAL; + + ret = regmap_read(regmap, SFR_OHCIICR, ®val); + if (ret) + return ret; + + if (enable) + regval &= ~SFR_OHCIICR_USB_SUSPEND; + else + regval |= SFR_OHCIICR_USB_SUSPEND; + + regmap_write(regmap, SFR_OHCIICR, regval); + + return 0; +} + +static int ohci_at91_port_suspend(struct regmap *regmap) +{ + return ohci_at91_port_ctrl(regmap, false); +} + +static int ohci_at91_port_resume(struct regmap *regmap) +{ + return ohci_at91_port_ctrl(regmap, true); +} + static int __maybe_unused ohci_hcd_at91_drv_suspend(struct device *dev) { @@ -618,6 +690,9 @@ ohci_hcd_at91_drv_suspend(struct device *dev) ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); ohci->rh_state = OHCI_RH_HALTED; + if (ohci_at91->caps->suspend_ctrl) + ohci_at91_port_suspend(ohci_at91->sfr_regmap); + /* flush the writes */ (void) ohci_readl (ohci, &ohci->regs->control); at91_stop_clock(ohci_at91); @@ -637,6 +712,9 @@ ohci_hcd_at91_drv_resume(struct device *dev) at91_start_clock(ohci_at91); + if (ohci_at91->caps->suspend_ctrl) + ohci_at91_port_resume(ohci_at91->sfr_regmap); + ohci_resume(hcd, false); return 0; } diff --git a/include/soc/at91/at91_sfr.h b/include/soc/at91/at91_sfr.h new file mode 100644 index 000000000000..04a3a1eee22e --- /dev/null +++ b/include/soc/at91/at91_sfr.h @@ -0,0 +1,29 @@ +/* + * Header file for the Atmel DDR/SDR SDRAM Controller + * + * Copyright (C) 2016 Atmel Corporation + * + * Author: Wenyou Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef __AT91_SFR_H__ +#define __AT91_SFR_H__ + +#define SFR_DDRCFG 0x04 /* DDR Configuration Register */ +/* 0x08 ~ 0x0c: Reserved */ +#define SFR_OHCIICR 0x10 /* OHCI Interrupt Configuration Register */ +#define SFR_OHCIISR 0x14 /* OHCI Interrupt Status Register */ + +#define SFR_OHCIICR_SUSPEND_A BIT(8) +#define SFR_OHCIICR_SUSPEND_B BIT(9) +#define SFR_OHCIICR_SUSPEND_C BIT(10) + +#define SFR_OHCIICR_USB_SUSPEND (SFR_OHCIICR_SUSPEND_A | \ + SFR_OHCIICR_SUSPEND_B | \ + SFR_OHCIICR_SUSPEND_C) + +#endif -- cgit v1.3-14-g43fede From 62d9694a003dba585026df36c181e3ca930aeafc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Jun 2016 17:14:06 +0200 Subject: ohci-platform: Add support for controllers with multiple reset lines At least the EHCI/OHCI found on the Allwinnner H3 SoC needs multiple reset lines, the controller will not initialize while the reset for its companion is still asserted, which means we need to de-assert 2 resets for the controller to work. Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-ohci.txt | 2 +- drivers/usb/host/ohci-platform.c | 43 ++++++++++++---------- 2 files changed, 24 insertions(+), 21 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt index 19233b7365e1..9df456968596 100644 --- a/Documentation/devicetree/bindings/usb/usb-ohci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt @@ -14,7 +14,7 @@ Optional properties: - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" -- resets : phandle + reset specifier pair +- resets : a list of phandle + reset specifier pairs Example: diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index ae1c988da146..898b74086c12 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -33,11 +33,12 @@ #define DRIVER_DESC "OHCI generic platform driver" #define OHCI_MAX_CLKS 3 +#define OHCI_MAX_RESETS 2 #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) struct ohci_platform_priv { struct clk *clks[OHCI_MAX_CLKS]; - struct reset_control *rst; + struct reset_control *resets[OHCI_MAX_RESETS]; struct phy **phys; int num_phys; }; @@ -117,7 +118,7 @@ static int ohci_platform_probe(struct platform_device *dev) struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); struct ohci_platform_priv *priv; struct ohci_hcd *ohci; - int err, irq, phy_num, clk = 0; + int err, irq, phy_num, clk = 0, rst = 0; if (usb_disabled()) return -ENODEV; @@ -195,19 +196,21 @@ static int ohci_platform_probe(struct platform_device *dev) break; } } - - } - - priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); - if (IS_ERR(priv->rst)) { - err = PTR_ERR(priv->rst); - if (err == -EPROBE_DEFER) - goto err_put_clks; - priv->rst = NULL; - } else { - err = reset_control_deassert(priv->rst); - if (err) - goto err_put_clks; + for (rst = 0; rst < OHCI_MAX_RESETS; rst++) { + priv->resets[rst] = + devm_reset_control_get_shared_by_index( + &dev->dev, rst); + if (IS_ERR(priv->resets[rst])) { + err = PTR_ERR(priv->resets[rst]); + if (err == -EPROBE_DEFER) + goto err_reset; + priv->resets[rst] = NULL; + break; + } + err = reset_control_deassert(priv->resets[rst]); + if (err) + goto err_reset; + } } if (pdata->big_endian_desc) @@ -265,8 +268,8 @@ err_power: if (pdata->power_off) pdata->power_off(dev); err_reset: - if (priv->rst) - reset_control_assert(priv->rst); + while (--rst >= 0) + reset_control_assert(priv->resets[rst]); err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); @@ -284,15 +287,15 @@ static int ohci_platform_remove(struct platform_device *dev) struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); - int clk; + int clk, rst; usb_remove_hcd(hcd); if (pdata->power_off) pdata->power_off(dev); - if (priv->rst) - reset_control_assert(priv->rst); + for (rst = 0; rst < OHCI_MAX_RESETS && priv->resets[rst]; rst++) + reset_control_assert(priv->resets[rst]); for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) clk_put(priv->clks[clk]); -- cgit v1.3-14-g43fede From 1a4d458bdf4694e014d54499348d101ffdb4cab5 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 4 Jun 2016 10:09:59 +0300 Subject: gpio: clps711x: Change the compatibility string This patch changes the compatibility string to match with the smallest supported chip (EP7209). Since the DT-support for this CPU is not yet announced, this change is safe. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/gpio/gpio-clps711x.txt | 4 ++-- drivers/gpio/gpio-clps711x.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt b/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt index e0d0446a6b78..0a304ad29d81 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt @@ -1,7 +1,7 @@ Cirrus Logic CLPS711X GPIO controller Required properties: -- compatible: Should be "cirrus,clps711x-gpio" +- compatible: Should be "cirrus,ep7209-gpio" - reg: Physical base GPIO controller registers location and length. There should be two registers, first is DATA register, the second is DIRECTION. @@ -21,7 +21,7 @@ aliases { }; porta: gpio@80000000 { - compatible = "cirrus,clps711x-gpio"; + compatible = "cirrus,ep7312-gpio","cirrus,ep7209-gpio"; reg = <0x80000000 0x1>, <0x80000040 0x1>; gpio-controller; #gpio-cells = <2>; diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index 5a690256af9b..cd3781e5622f 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -71,7 +71,7 @@ static int clps711x_gpio_probe(struct platform_device *pdev) } static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = { - { .compatible = "cirrus,clps711x-gpio" }, + { .compatible = "cirrus,ep7209-gpio" }, { } }; MODULE_DEVICE_TABLE(of, clps711x_gpio_ids); -- cgit v1.3-14-g43fede From 2e607fca7a2f842c73cf0c12ea4cf4776bdf7e46 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 4 Jun 2016 10:10:00 +0300 Subject: gpio: syscon: Change the compatibility string This patch changes the compatibility string to match with the smallest supported chip (EP7209). Since the DT-support for this CPU is not yet announced, this change is safe. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/gpio/cirrus,clps711x-mctrl-gpio.txt | 4 ++-- drivers/gpio/gpio-syscon.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/cirrus,clps711x-mctrl-gpio.txt b/Documentation/devicetree/bindings/gpio/cirrus,clps711x-mctrl-gpio.txt index 94ae9f82dcf8..fd42e7280f72 100644 --- a/Documentation/devicetree/bindings/gpio/cirrus,clps711x-mctrl-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/cirrus,clps711x-mctrl-gpio.txt @@ -1,7 +1,7 @@ * ARM Cirrus Logic CLPS711X SYSFLG1 MCTRL GPIOs Required properties: -- compatible: Should contain "cirrus,clps711x-mctrl-gpio". +- compatible: Should contain "cirrus,ep7209-mctrl-gpio". - gpio-controller: Marks the device node as a gpio controller. - #gpio-cells: Should be two. The first cell is the pin number and the second cell is used to specify the gpio polarity: @@ -11,7 +11,7 @@ Required properties: Example: sysgpio: sysgpio { compatible = "cirrus,ep7312-mctrl-gpio", - "cirrus,clps711x-mctrl-gpio"; + "cirrus,ep7209-mctrl-gpio"; gpio-controller; #gpio-cells = <2>; }; diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index 24b6d643ecdb..537cec7583fc 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c @@ -129,7 +129,7 @@ static int syscon_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int val) static const struct syscon_gpio_data clps711x_mctrl_gpio = { /* ARM CLPS711X SYSFLG1 Bits 8-10 */ - .compatible = "cirrus,clps711x-syscon1", + .compatible = "cirrus,ep7209-syscon1", .flags = GPIO_SYSCON_FEAT_IN, .bit_count = 3, .dat_bit_offset = 0x40 * 8 + 8, @@ -168,7 +168,7 @@ static const struct syscon_gpio_data keystone_dsp_gpio = { static const struct of_device_id syscon_gpio_ids[] = { { - .compatible = "cirrus,clps711x-mctrl-gpio", + .compatible = "cirrus,ep7209-mctrl-gpio", .data = &clps711x_mctrl_gpio, }, { -- cgit v1.3-14-g43fede From 9f3cc2a0772d7744d1d7195d39ac4794af622fe6 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 6 Jun 2016 17:10:50 +0200 Subject: Documentation/microcode: Document some aspects for more clarity Document that builtin microcode is 64-bit only. Also, improve/add comments to places. Signed-off-by: Borislav Petkov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/1465225850-7352-10-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- Documentation/x86/early-microcode.txt | 5 ++++- arch/x86/kernel/cpu/microcode/intel.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/x86/early-microcode.txt b/Documentation/x86/early-microcode.txt index c956d99cf1de..07749e7f3d50 100644 --- a/Documentation/x86/early-microcode.txt +++ b/Documentation/x86/early-microcode.txt @@ -45,7 +45,10 @@ Builtin microcode ================= We can also load builtin microcode supplied through the regular firmware -builtin method CONFIG_FIRMWARE_IN_KERNEL. Here's an example: +builtin method CONFIG_FIRMWARE_IN_KERNEL. Only 64-bit is currently +supported. + +Here's an example: CONFIG_FIRMWARE_IN_KERNEL=y CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 359e2034b558..8962d6acee39 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -40,9 +40,13 @@ #include /* - * Temporary microcode blobs pointers storage. We note here the pointers to - * microcode blobs we've got from whatever storage (detached initrd, builtin). - * Later on, we put those into final storage mc_saved_data.mc_saved. + * Temporary microcode blobs pointers storage. We note here during early load + * the pointers to microcode blobs we've got from whatever storage (detached + * initrd, builtin). Later on, we put those into final storage + * mc_saved_data.mc_saved. + * + * Important: those are offsets from the beginning of initrd or absolute + * addresses within the kernel image when built-in. */ static unsigned long mc_tmp_ptrs[MAX_UCODE_COUNT]; @@ -57,6 +61,7 @@ static struct ucode_blobs { bool valid; } blobs; +/* Go through saved patches and find the one suitable for the current CPU. */ static enum ucode_state find_microcode_patch(struct microcode_intel **saved, unsigned int num_saved, struct ucode_cpu_info *uci) @@ -466,6 +471,7 @@ static void show_saved_mc(void) static void save_mc_for_early(u8 *mc) { #ifdef CONFIG_HOTPLUG_CPU + /* Synchronization during CPU hotplug. */ static DEFINE_MUTEX(x86_cpu_microcode_mutex); struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT]; @@ -474,10 +480,6 @@ static void save_mc_for_early(u8 *mc) struct microcode_intel **mc_saved; int ret, i; - /* - * Hold hotplug lock so mc_saved_data is not accessed by a CPU in - * hotplug. - */ mutex_lock(&x86_cpu_microcode_mutex); mc_saved_count_init = mc_saved_data.num_saved; -- cgit v1.3-14-g43fede From 7ab4aabbaa98fbf9f8967fd93162d675439337e1 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 3 Jun 2016 10:58:49 +0530 Subject: cpufreq: Drop freq-table param to cpufreq_frequency_table_target() The policy already has this pointer set, use it instead. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/cpu-drivers.txt | 1 - drivers/cpufreq/amd_freq_sensitivity.c | 3 +-- drivers/cpufreq/cpufreq.c | 4 ++-- drivers/cpufreq/cpufreq_ondemand.c | 11 +++++------ drivers/cpufreq/freq_table.c | 2 +- drivers/cpufreq/powernv-cpufreq.c | 3 +-- drivers/cpufreq/s3c24xx-cpufreq.c | 11 +++++------ drivers/cpufreq/s5pv210-cpufreq.c | 3 +-- include/linux/cpufreq.h | 1 - 9 files changed, 16 insertions(+), 23 deletions(-) (limited to 'Documentation') diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index decbb8cb5573..74e812f0719c 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -244,7 +244,6 @@ policy->max, and all other criteria are met. This is helpful for the ->verify call. int cpufreq_frequency_table_target(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table, unsigned int target_freq, unsigned int relation, unsigned int *index); diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c index bc86816693a8..3bea1bb791a9 100644 --- a/drivers/cpufreq/amd_freq_sensitivity.c +++ b/drivers/cpufreq/amd_freq_sensitivity.c @@ -92,8 +92,7 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy, unsigned int index; cpufreq_frequency_table_target(policy, - policy->freq_table, policy->cur - 1, - CPUFREQ_RELATION_H, &index); + policy->cur - 1, CPUFREQ_RELATION_H, &index); freq_next = policy->freq_table[index].frequency; } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index cc252eecc45a..a28144697128 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1947,8 +1947,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, return -EINVAL; } - retval = cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &index); + retval = cpufreq_frequency_table_target(policy, target_freq, relation, + &index); if (unlikely(retval)) { pr_err("%s: Unable to find matching freq\n", __func__); return retval; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 528353f204fd..2ee476f5a2bd 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -79,20 +79,19 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, return freq_next; } - cpufreq_frequency_table_target(policy, freq_table, freq_next, relation, - &index); + cpufreq_frequency_table_target(policy, freq_next, relation, &index); freq_req = freq_table[index].frequency; freq_reduc = freq_req * od_tuners->powersave_bias / 1000; freq_avg = freq_req - freq_reduc; /* Find freq bounds for freq_avg in freq_table */ index = 0; - cpufreq_frequency_table_target(policy, freq_table, freq_avg, - CPUFREQ_RELATION_H, &index); + cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_H, + &index); freq_lo = freq_table[index].frequency; index = 0; - cpufreq_frequency_table_target(policy, freq_table, freq_avg, - CPUFREQ_RELATION_L, &index); + cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_L, + &index); freq_hi = freq_table[index].frequency; /* Find out how long we have to be in hi and lo freqs */ diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index f52b5473b1f4..f145b64649ef 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -114,7 +114,6 @@ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table, unsigned int target_freq, unsigned int relation, unsigned int *index) @@ -128,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, .frequency = 0, }; struct cpufreq_frequency_table *pos; + struct cpufreq_frequency_table *table = policy->freq_table; unsigned int freq, diff, i = 0; pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 54c45368e3f1..bf267c2dfe20 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -760,8 +760,7 @@ void powernv_cpufreq_work_fn(struct work_struct *work) struct cpufreq_policy policy; cpufreq_get_policy(&policy, cpu); - cpufreq_frequency_table_target(&policy, policy.freq_table, - policy.cur, + cpufreq_frequency_table_target(&policy, policy.cur, CPUFREQ_RELATION_C, &index); powernv_cpufreq_target_index(&policy, index); cpumask_andnot(&mask, &mask, policy.cpus); diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 4567c3cab095..05a9737278f3 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -293,9 +293,8 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, __func__, policy, target_freq, relation); if (ftab) { - if (cpufreq_frequency_table_target(policy, ftab, - target_freq, relation, - &index)) { + if (cpufreq_frequency_table_target(policy, target_freq, + relation, &index)) { s3c_freq_dbg("%s: table failed\n", __func__); return -EINVAL; } @@ -323,14 +322,14 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, tmp_policy.min = policy->min * 1000; tmp_policy.max = policy->max * 1000; tmp_policy.cpu = policy->cpu; + tmp_policy.freq_table = pll_reg; /* cpufreq_frequency_table_target uses a pointer to 'index' * which is the number of the table entry, not the value of * the table entry's index field. */ - ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg, - target_freq, relation, - &index); + ret = cpufreq_frequency_table_target(&tmp_policy, target_freq, + relation, &index); if (ret < 0) { pr_err("%s: no PLL available\n", __func__); diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 06d85917b6d5..6b0cfc3b8c46 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -246,8 +246,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) new_freq = s5pv210_freq_table[index].frequency; /* Finding current running level index */ - if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, - old_freq, CPUFREQ_RELATION_H, + if (cpufreq_frequency_table_target(policy, old_freq, CPUFREQ_RELATION_H, &priv_index)) { ret = -EINVAL; goto exit; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 1342cbc0f25e..bdd7f0c035ae 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -598,7 +598,6 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table, unsigned int target_freq, unsigned int relation, unsigned int *index); -- cgit v1.3-14-g43fede From d218ed773915a2b762d132be6bb765637338c360 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 3 Jun 2016 10:58:51 +0530 Subject: cpufreq: Return index from cpufreq_frequency_table_target() This routine can't fail unless the frequency table is invalid and doesn't contain any valid entries. Make it return the index and WARN() in case it is used for an invalid table. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/cpu-drivers.txt | 7 +++---- drivers/cpufreq/amd_freq_sensitivity.c | 4 ++-- drivers/cpufreq/cpufreq.c | 9 ++------- drivers/cpufreq/cpufreq_ondemand.c | 14 ++++++-------- drivers/cpufreq/freq_table.c | 24 +++++++++++++----------- drivers/cpufreq/powernv-cpufreq.c | 4 ++-- drivers/cpufreq/s3c24xx-cpufreq.c | 26 ++++++-------------------- drivers/cpufreq/s5pv210-cpufreq.c | 7 ++----- include/linux/cpufreq.h | 3 +-- 9 files changed, 37 insertions(+), 61 deletions(-) (limited to 'Documentation') diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index 74e812f0719c..772b94fde264 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -245,12 +245,11 @@ policy->max, and all other criteria are met. This is helpful for the int cpufreq_frequency_table_target(struct cpufreq_policy *policy, unsigned int target_freq, - unsigned int relation, - unsigned int *index); + unsigned int relation); is the corresponding frequency table helper for the ->target -stage. Just pass the values to this function, and the unsigned int -index returns the number of the frequency table entry which contains +stage. Just pass the values to this function, and this function +returns the number of the frequency table entry which contains the frequency the CPU shall be set to. The following macros can be used as iterators over cpufreq_frequency_table: diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c index 3bea1bb791a9..6d5dc04c3a37 100644 --- a/drivers/cpufreq/amd_freq_sensitivity.c +++ b/drivers/cpufreq/amd_freq_sensitivity.c @@ -91,8 +91,8 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy, else { unsigned int index; - cpufreq_frequency_table_target(policy, - policy->cur - 1, CPUFREQ_RELATION_H, &index); + index = cpufreq_frequency_table_target(policy, + policy->cur - 1, CPUFREQ_RELATION_H); freq_next = policy->freq_table[index].frequency; } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1685e930770f..07c933c6c29a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1914,7 +1914,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int relation) { unsigned int old_target_freq = target_freq; - int index, retval; + int index; if (cpufreq_disabled()) return -ENODEV; @@ -1943,12 +1943,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, if (!cpufreq_driver->target_index) return -EINVAL; - retval = cpufreq_frequency_table_target(policy, target_freq, relation, - &index); - if (unlikely(retval)) { - pr_err("%s: Unable to find matching freq\n", __func__); - return retval; - } + index = cpufreq_frequency_table_target(policy, target_freq, relation); return __target_index(policy, index); } diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 2ee476f5a2bd..0c93cd9dee99 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -65,7 +65,7 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, { unsigned int freq_req, freq_reduc, freq_avg; unsigned int freq_hi, freq_lo; - unsigned int index = 0; + unsigned int index; unsigned int delay_hi_us; struct policy_dbs_info *policy_dbs = policy->governor_data; struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs); @@ -79,19 +79,17 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, return freq_next; } - cpufreq_frequency_table_target(policy, freq_next, relation, &index); + index = cpufreq_frequency_table_target(policy, freq_next, relation); freq_req = freq_table[index].frequency; freq_reduc = freq_req * od_tuners->powersave_bias / 1000; freq_avg = freq_req - freq_reduc; /* Find freq bounds for freq_avg in freq_table */ - index = 0; - cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_H, - &index); + index = cpufreq_frequency_table_target(policy, freq_avg, + CPUFREQ_RELATION_H); freq_lo = freq_table[index].frequency; - index = 0; - cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_L, - &index); + index = cpufreq_frequency_table_target(policy, freq_avg, + CPUFREQ_RELATION_L); freq_hi = freq_table[index].frequency; /* Find out how long we have to be in hi and lo freqs */ diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index f145b64649ef..eac8bcbdaad1 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -114,9 +114,8 @@ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation, - unsigned int *index) + unsigned int target_freq, + unsigned int relation) { struct cpufreq_frequency_table optimal = { .driver_data = ~0, @@ -129,6 +128,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, struct cpufreq_frequency_table *pos; struct cpufreq_frequency_table *table = policy->freq_table; unsigned int freq, diff, i = 0; + int index; pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", target_freq, relation, policy->cpu); @@ -192,16 +192,18 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, } } if (optimal.driver_data > i) { - if (suboptimal.driver_data > i) - return -EINVAL; - *index = suboptimal.driver_data; - } else - *index = optimal.driver_data; + if (suboptimal.driver_data > i) { + WARN(1, "Invalid frequency table: %d\n", policy->cpu); + return 0; + } - pr_debug("target index is %u, freq is:%u kHz\n", *index, - table[*index].frequency); + index = suboptimal.driver_data; + } else + index = optimal.driver_data; - return 0; + pr_debug("target index is %u, freq is:%u kHz\n", index, + table[index].frequency); + return index; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index bf267c2dfe20..b29c5c20c3a1 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -760,8 +760,8 @@ void powernv_cpufreq_work_fn(struct work_struct *work) struct cpufreq_policy policy; cpufreq_get_policy(&policy, cpu); - cpufreq_frequency_table_target(&policy, policy.cur, - CPUFREQ_RELATION_C, &index); + index = cpufreq_frequency_table_target(&policy, policy.cur, + CPUFREQ_RELATION_C); powernv_cpufreq_target_index(&policy, index); cpumask_andnot(&mask, &mask, policy.cpus); } diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 05a9737278f3..7b596fa38ad2 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -293,11 +293,8 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, __func__, policy, target_freq, relation); if (ftab) { - if (cpufreq_frequency_table_target(policy, target_freq, - relation, &index)) { - s3c_freq_dbg("%s: table failed\n", __func__); - return -EINVAL; - } + index = cpufreq_frequency_table_target(policy, target_freq, + relation); s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__, target_freq, index, ftab[index].frequency); @@ -314,7 +311,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, pll = NULL; } else { struct cpufreq_policy tmp_policy; - int ret; /* we keep the cpu pll table in Hz, to ensure we get an * accurate value for the PLL output. */ @@ -324,18 +320,12 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, tmp_policy.cpu = policy->cpu; tmp_policy.freq_table = pll_reg; - /* cpufreq_frequency_table_target uses a pointer to 'index' - * which is the number of the table entry, not the value of + /* cpufreq_frequency_table_target returns the index + * of the table entry, not the value of * the table entry's index field. */ - ret = cpufreq_frequency_table_target(&tmp_policy, target_freq, - relation, &index); - - if (ret < 0) { - pr_err("%s: no PLL available\n", __func__); - goto err_notpossible; - } - + index = cpufreq_frequency_table_target(&tmp_policy, target_freq, + relation); pll = pll_reg + index; s3c_freq_dbg("%s: target %u => %u\n", @@ -345,10 +335,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, } return s3c_cpufreq_settarget(policy, target_freq, pll); - - err_notpossible: - pr_err("no compatible settings for %d\n", target_freq); - return -EINVAL; } struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 6b0cfc3b8c46..4f4e9df9b7fc 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -246,11 +246,8 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) new_freq = s5pv210_freq_table[index].frequency; /* Finding current running level index */ - if (cpufreq_frequency_table_target(policy, old_freq, CPUFREQ_RELATION_H, - &priv_index)) { - ret = -EINVAL; - goto exit; - } + priv_index = cpufreq_frequency_table_target(policy, old_freq, + CPUFREQ_RELATION_H); arm_volt = dvs_conf[index].arm_volt; int_volt = dvs_conf[index].int_volt; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index bdd7f0c035ae..c378776628b4 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -599,8 +599,7 @@ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy); int cpufreq_frequency_table_target(struct cpufreq_policy *policy, unsigned int target_freq, - unsigned int relation, - unsigned int *index); + unsigned int relation); int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, unsigned int freq); -- cgit v1.3-14-g43fede From ae4df11a0f538b83781cf120a78dde32b0070600 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 9 Jun 2016 12:54:08 +0300 Subject: drm: Move format-related helpers to drm_fourcc.c The drm_crtc.c file is a mess, making the ABI documentation confusing since all functions are in the same bag. Split the format-related helpers to a new drm_fourcc.c file. Signed-off-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465466048-2020-1-git-send-email-laurent.pinchart@ideasonboard.com --- Documentation/DocBook/gpu.tmpl | 5 + drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_crtc.c | 289 ------------------------------------- drivers/gpu/drm/drm_fourcc.c | 320 +++++++++++++++++++++++++++++++++++++++++ include/drm/drmP.h | 1 + include/drm/drm_crtc.h | 9 -- include/drm/drm_fourcc.h | 37 +++++ 7 files changed, 364 insertions(+), 299 deletions(-) create mode 100644 drivers/gpu/drm/drm_fourcc.c create mode 100644 include/drm/drm_fourcc.h (limited to 'Documentation') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index dac18b4ff090..89585ad69a4b 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1017,6 +1017,11 @@ int max_width, max_height; drm_framebuffer_unregister_private. + + DRM Format Handling +!Iinclude/drm/drm_fourcc.h +!Edrivers/gpu/drm/drm_fourcc.c + Dumb Buffer Objects diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index be43afb08c69..aa24af35c068 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -8,7 +8,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_lock.o drm_memory.o drm_drv.o drm_vm.o \ drm_scatter.o drm_pci.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ - drm_crtc.o drm_modes.o drm_edid.o \ + drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ drm_trace_points.o drm_global.o drm_prime.o \ drm_rect.o drm_vma_manager.o drm_flip_work.o \ diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index df91dfe506eb..aeb5d9e087fc 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -239,37 +239,6 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order) } EXPORT_SYMBOL(drm_get_subpixel_order_name); -static char printable_char(int c) -{ - return isascii(c) && isprint(c) ? c : '?'; -} - -/** - * drm_get_format_name - return a string for drm fourcc format - * @format: format to compute name of - * - * Note that the buffer used by this function is globally shared and owned by - * the function itself. - * - * FIXME: This isn't really multithreading safe. - */ -const char *drm_get_format_name(uint32_t format) -{ - static char buf[32]; - - snprintf(buf, sizeof(buf), - "%c%c%c%c %s-endian (0x%08x)", - printable_char(format & 0xff), - printable_char((format >> 8) & 0xff), - printable_char((format >> 16) & 0xff), - printable_char((format >> 24) & 0x7f), - format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", - format); - - return buf; -} -EXPORT_SYMBOL(drm_get_format_name); - /* * Internal function to assign a slot in the object idr and optionally * register the object into the idr. @@ -5502,264 +5471,6 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, return dev->driver->dumb_destroy(file_priv, dev, args->handle); } -/** - * drm_fb_get_bpp_depth - get the bpp/depth values for format - * @format: pixel format (DRM_FORMAT_*) - * @depth: storage for the depth value - * @bpp: storage for the bpp value - * - * This only supports RGB formats here for compat with code that doesn't use - * pixel formats directly yet. - */ -void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, - int *bpp) -{ - switch (format) { - case DRM_FORMAT_C8: - case DRM_FORMAT_RGB332: - case DRM_FORMAT_BGR233: - *depth = 8; - *bpp = 8; - break; - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XBGR1555: - case DRM_FORMAT_RGBX5551: - case DRM_FORMAT_BGRX5551: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ABGR1555: - case DRM_FORMAT_RGBA5551: - case DRM_FORMAT_BGRA5551: - *depth = 15; - *bpp = 16; - break; - case DRM_FORMAT_RGB565: - case DRM_FORMAT_BGR565: - *depth = 16; - *bpp = 16; - break; - case DRM_FORMAT_RGB888: - case DRM_FORMAT_BGR888: - *depth = 24; - *bpp = 24; - break; - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_RGBX8888: - case DRM_FORMAT_BGRX8888: - *depth = 24; - *bpp = 32; - break; - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_RGBA1010102: - case DRM_FORMAT_BGRA1010102: - *depth = 30; - *bpp = 32; - break; - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_RGBA8888: - case DRM_FORMAT_BGRA8888: - *depth = 32; - *bpp = 32; - break; - default: - DRM_DEBUG_KMS("unsupported pixel format %s\n", - drm_get_format_name(format)); - *depth = 0; - *bpp = 0; - break; - } -} -EXPORT_SYMBOL(drm_fb_get_bpp_depth); - -/** - * drm_format_num_planes - get the number of planes for format - * @format: pixel format (DRM_FORMAT_*) - * - * Returns: - * The number of planes used by the specified pixel format. - */ -int drm_format_num_planes(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YVU410: - case DRM_FORMAT_YUV411: - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YUV422: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YUV444: - case DRM_FORMAT_YVU444: - return 3; - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV61: - case DRM_FORMAT_NV24: - case DRM_FORMAT_NV42: - return 2; - default: - return 1; - } -} -EXPORT_SYMBOL(drm_format_num_planes); - -/** - * drm_format_plane_cpp - determine the bytes per pixel value - * @format: pixel format (DRM_FORMAT_*) - * @plane: plane index - * - * Returns: - * The bytes per pixel value for the specified plane. - */ -int drm_format_plane_cpp(uint32_t format, int plane) -{ - unsigned int depth; - int bpp; - - if (plane >= drm_format_num_planes(format)) - return 0; - - switch (format) { - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - return 2; - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV61: - case DRM_FORMAT_NV24: - case DRM_FORMAT_NV42: - return plane ? 2 : 1; - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YVU410: - case DRM_FORMAT_YUV411: - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YUV422: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YUV444: - case DRM_FORMAT_YVU444: - return 1; - default: - drm_fb_get_bpp_depth(format, &depth, &bpp); - return bpp >> 3; - } -} -EXPORT_SYMBOL(drm_format_plane_cpp); - -/** - * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor - * @format: pixel format (DRM_FORMAT_*) - * - * Returns: - * The horizontal chroma subsampling factor for the - * specified pixel format. - */ -int drm_format_horz_chroma_subsampling(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_YUV411: - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YVU410: - return 4; - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV61: - case DRM_FORMAT_YUV422: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - return 2; - default: - return 1; - } -} -EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); - -/** - * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor - * @format: pixel format (DRM_FORMAT_*) - * - * Returns: - * The vertical chroma subsampling factor for the - * specified pixel format. - */ -int drm_format_vert_chroma_subsampling(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YVU410: - return 4; - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - return 2; - default: - return 1; - } -} -EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); - -/** - * drm_format_plane_width - width of the plane given the first plane - * @width: width of the first plane - * @format: pixel format - * @plane: plane index - * - * Returns: - * The width of @plane, given that the width of the first plane is @width. - */ -int drm_format_plane_width(int width, uint32_t format, int plane) -{ - if (plane >= drm_format_num_planes(format)) - return 0; - - if (plane == 0) - return width; - - return width / drm_format_horz_chroma_subsampling(format); -} -EXPORT_SYMBOL(drm_format_plane_width); - -/** - * drm_format_plane_height - height of the plane given the first plane - * @height: height of the first plane - * @format: pixel format - * @plane: plane index - * - * Returns: - * The height of @plane, given that the height of the first plane is @height. - */ -int drm_format_plane_height(int height, uint32_t format, int plane) -{ - if (plane >= drm_format_num_planes(format)) - return 0; - - if (plane == 0) - return height; - - return height / drm_format_vert_chroma_subsampling(format); -} -EXPORT_SYMBOL(drm_format_plane_height); - /** * drm_rotation_simplify() - Try to simplify the rotation * @rotation: Rotation to be simplified diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c new file mode 100644 index 000000000000..0645c85d5f95 --- /dev/null +++ b/drivers/gpu/drm/drm_fourcc.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2016 Laurent Pinchart + * + * DRM core format related functions + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include + +static char printable_char(int c) +{ + return isascii(c) && isprint(c) ? c : '?'; +} + +/** + * drm_get_format_name - return a string for drm fourcc format + * @format: format to compute name of + * + * Note that the buffer used by this function is globally shared and owned by + * the function itself. + * + * FIXME: This isn't really multithreading safe. + */ +const char *drm_get_format_name(uint32_t format) +{ + static char buf[32]; + + snprintf(buf, sizeof(buf), + "%c%c%c%c %s-endian (0x%08x)", + printable_char(format & 0xff), + printable_char((format >> 8) & 0xff), + printable_char((format >> 16) & 0xff), + printable_char((format >> 24) & 0x7f), + format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", + format); + + return buf; +} +EXPORT_SYMBOL(drm_get_format_name); + +/** + * drm_fb_get_bpp_depth - get the bpp/depth values for format + * @format: pixel format (DRM_FORMAT_*) + * @depth: storage for the depth value + * @bpp: storage for the bpp value + * + * This only supports RGB formats here for compat with code that doesn't use + * pixel formats directly yet. + */ +void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, + int *bpp) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB332: + case DRM_FORMAT_BGR233: + *depth = 8; + *bpp = 8; + break; + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XBGR1555: + case DRM_FORMAT_RGBX5551: + case DRM_FORMAT_BGRX5551: + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_BGRA5551: + *depth = 15; + *bpp = 16; + break; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + *depth = 16; + *bpp = 16; + break; + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + *depth = 24; + *bpp = 24; + break; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_BGRX8888: + *depth = 24; + *bpp = 32; + break; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_BGRX1010102: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRA1010102: + *depth = 30; + *bpp = 32; + break; + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_RGBA8888: + case DRM_FORMAT_BGRA8888: + *depth = 32; + *bpp = 32; + break; + default: + DRM_DEBUG_KMS("unsupported pixel format %s\n", + drm_get_format_name(format)); + *depth = 0; + *bpp = 0; + break; + } +} +EXPORT_SYMBOL(drm_fb_get_bpp_depth); + +/** + * drm_format_num_planes - get the number of planes for format + * @format: pixel format (DRM_FORMAT_*) + * + * Returns: + * The number of planes used by the specified pixel format. + */ +int drm_format_num_planes(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_YVU444: + return 3; + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV42: + return 2; + default: + return 1; + } +} +EXPORT_SYMBOL(drm_format_num_planes); + +/** + * drm_format_plane_cpp - determine the bytes per pixel value + * @format: pixel format (DRM_FORMAT_*) + * @plane: plane index + * + * Returns: + * The bytes per pixel value for the specified plane. + */ +int drm_format_plane_cpp(uint32_t format, int plane) +{ + unsigned int depth; + int bpp; + + if (plane >= drm_format_num_planes(format)) + return 0; + + switch (format) { + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + return 2; + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + case DRM_FORMAT_NV24: + case DRM_FORMAT_NV42: + return plane ? 2 : 1; + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_YVU444: + return 1; + default: + drm_fb_get_bpp_depth(format, &depth, &bpp); + return bpp >> 3; + } +} +EXPORT_SYMBOL(drm_format_plane_cpp); + +/** + * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor + * @format: pixel format (DRM_FORMAT_*) + * + * Returns: + * The horizontal chroma subsampling factor for the + * specified pixel format. + */ +int drm_format_horz_chroma_subsampling(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + return 4; + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + return 2; + default: + return 1; + } +} +EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); + +/** + * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor + * @format: pixel format (DRM_FORMAT_*) + * + * Returns: + * The vertical chroma subsampling factor for the + * specified pixel format. + */ +int drm_format_vert_chroma_subsampling(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + return 4; + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + return 2; + default: + return 1; + } +} +EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); + +/** + * drm_format_plane_width - width of the plane given the first plane + * @width: width of the first plane + * @format: pixel format + * @plane: plane index + * + * Returns: + * The width of @plane, given that the width of the first plane is @width. + */ +int drm_format_plane_width(int width, uint32_t format, int plane) +{ + if (plane >= drm_format_num_planes(format)) + return 0; + + if (plane == 0) + return width; + + return width / drm_format_horz_chroma_subsampling(format); +} +EXPORT_SYMBOL(drm_format_plane_width); + +/** + * drm_format_plane_height - height of the plane given the first plane + * @height: height of the first plane + * @format: pixel format + * @plane: plane index + * + * Returns: + * The height of @plane, given that the height of the first plane is @height. + */ +int drm_format_plane_height(int height, uint32_t format, int plane) +{ + if (plane >= drm_format_num_planes(format)) + return 0; + + if (plane == 0) + return height; + + return height / drm_format_vert_chroma_subsampling(format); +} +EXPORT_SYMBOL(drm_format_plane_height); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index a4f9babce249..086ad96d7d62 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -68,6 +68,7 @@ #include #include +#include #include #include #include diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 1a8d66ca677c..7bf065b61316 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -2645,15 +2645,6 @@ extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane, extern int drm_mode_atomic_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, - int *bpp); -extern int drm_format_num_planes(uint32_t format); -extern int drm_format_plane_cpp(uint32_t format, int plane); -extern int drm_format_horz_chroma_subsampling(uint32_t format); -extern int drm_format_vert_chroma_subsampling(uint32_t format); -extern int drm_format_plane_width(int width, uint32_t format, int plane); -extern int drm_format_plane_height(int height, uint32_t format, int plane); -extern const char *drm_get_format_name(uint32_t format); extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, unsigned int supported_rotations); extern unsigned int drm_rotation_simplify(unsigned int rotation, diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h new file mode 100644 index 000000000000..7f90a396cf2b --- /dev/null +++ b/include/drm/drm_fourcc.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Laurent Pinchart + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ +#ifndef __DRM_FOURCC_H__ +#define __DRM_FOURCC_H__ + +#include +#include + +void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); +int drm_format_num_planes(uint32_t format); +int drm_format_plane_cpp(uint32_t format, int plane); +int drm_format_horz_chroma_subsampling(uint32_t format); +int drm_format_vert_chroma_subsampling(uint32_t format); +int drm_format_plane_width(int width, uint32_t format, int plane); +int drm_format_plane_height(int height, uint32_t format, int plane); +const char *drm_get_format_name(uint32_t format); + +#endif /* __DRM_FOURCC_H__ */ -- cgit v1.3-14-g43fede From 7dc20319660d12d2ef642e572e8802c228b6c1cd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 9 Jun 2016 03:21:37 +0000 Subject: ASoC: rsnd: adg :: AUDIO-CLKOUTn asynchronizes support AUDIO-CLKOUTn can asynchronizes with L/R clock. AUDIO-CLKOUTn synchronizes with L/R clock is now default behavior. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/renesas,rsnd.txt | 2 ++ sound/soc/sh/rcar/adg.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index c7b29df4a963..15a7316e4c91 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -373,6 +373,8 @@ Optional properties: - #clock-cells : it must be 0 if your system has audio_clkout it must be 1 if your system has audio_clkout0/1/2/3 - clock-frequency : for all audio_clkout0/1/2/3 +- clkout-lr-asynchronous : boolean property. it indicates that audio_clkoutn + is asynchronizes with lr-clock. SSI subnode properties: - interrupts : Should contain SSI interrupt for PIO transfer diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 49354d17ea55..7d3e0e46d64a 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -33,11 +33,15 @@ struct rsnd_adg { struct clk *clkout[CLKOUTMAX]; struct clk_onecell_data onecell; struct rsnd_mod mod; + u32 flags; int rbga_rate_for_441khz; /* RBGA */ int rbgb_rate_for_48khz; /* RBGB */ }; +#define LRCLK_ASYNC (1 << 0) +#define adg_mode_flags(adg) (adg->flags) + #define for_each_rsnd_clk(pos, adg, i) \ for (i = 0; \ (i < CLKMAX) && \ @@ -355,6 +359,16 @@ found_clock: rsnd_adg_set_ssi_clk(ssi_mod, data); + if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) { + struct rsnd_mod *adg_mod = rsnd_mod_get(adg); + u32 ckr = 0; + + if (0 == (rate % 8000)) + ckr = 0x80000000; + + rsnd_mod_bset(adg_mod, SSICKR, 0x80000000, ckr); + } + dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n", rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod), data, rate); @@ -532,6 +546,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv) { struct rsnd_adg *adg; struct device *dev = rsnd_priv_to_dev(priv); + struct device_node *np = dev->of_node; adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); if (!adg) { @@ -545,6 +560,9 @@ int rsnd_adg_probe(struct rsnd_priv *priv) rsnd_adg_get_clkin(priv, adg); rsnd_adg_get_clkout(priv, adg); + if (of_get_property(np, "clkout-lr-asynchronous", NULL)) + adg->flags = LRCLK_ASYNC; + priv->adg = adg; return 0; -- cgit v1.3-14-g43fede From c9de4a82c852d621975f5978157f689e0550a48e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 18 May 2016 06:37:47 -0700 Subject: docs: self-protection: rename "leak" to "exposure" The meaning of "leak" can be both "untracked resource allocation" and "memory content disclosure". This document's use was entirely of the latter meaning, so avoid the confusion by using the Common Weakness Enumeration name for this: Information Exposure (CWE-200). Additionally adds a section on structure randomization. Signed-off-by: Kees Cook Signed-off-by: Jonathan Corbet --- Documentation/security/self-protection.txt | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/security/self-protection.txt b/Documentation/security/self-protection.txt index babd6378ec05..3010576c9fca 100644 --- a/Documentation/security/self-protection.txt +++ b/Documentation/security/self-protection.txt @@ -183,8 +183,9 @@ provide meaningful defenses. ### Canaries, blinding, and other secrets It should be noted that things like the stack canary discussed earlier -are technically statistical defenses, since they rely on a (leakable) -secret value. +are technically statistical defenses, since they rely on a secret value, +and such values may become discoverable through an information exposure +flaw. Blinding literal values for things like JITs, where the executable contents may be partially under the control of userspace, need a similar @@ -199,8 +200,8 @@ working?) in order to maximize their success. Since the location of kernel memory is almost always instrumental in mounting a successful attack, making the location non-deterministic raises the difficulty of an exploit. (Note that this in turn makes -the value of leaks higher, since they may be used to discover desired -memory locations.) +the value of information exposures higher, since they may be used to +discover desired memory locations.) #### Text and module base @@ -222,14 +223,21 @@ become more difficult to locate. Much of the kernel's dynamic memory (e.g. kmalloc, vmalloc, etc) ends up being relatively deterministic in layout due to the order of early-boot initializations. If the base address of these areas is not the same -between boots, targeting them is frustrated, requiring a leak specific -to the region. +between boots, targeting them is frustrated, requiring an information +exposure specific to the region. + +#### Structure layout + +By performing a per-build randomization of the layout of sensitive +structures, attacks must either be tuned to known kernel builds or expose +enough kernel memory to determine structure layouts before manipulating +them. -## Preventing Leaks +## Preventing Information Exposures Since the locations of sensitive structures are the primary target for -attacks, it is important to defend against leaks of both kernel memory +attacks, it is important to defend against exposure of both kernel memory addresses and kernel memory contents (since they may contain kernel addresses or other sensitive things like canary values). @@ -250,8 +258,8 @@ sure structure holes are cleared. When releasing memory, it is best to poison the contents (clear stack on syscall return, wipe heap memory on a free), to avoid reuse attacks that rely on the old contents of memory. This frustrates many uninitialized -variable attacks, stack info leaks, heap info leaks, and use-after-free -attacks. +variable attacks, stack content exposures, heap content exposures, and +use-after-free attacks. ### Destination tracking -- cgit v1.3-14-g43fede From cecbf8d52e6c7f16d954091be9283b928199ed92 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Jun 2016 19:18:53 +0200 Subject: power: axp20x_usb: Add support for usb power-supply on axp22x pmics The usb power-supply on the axp22x pmics is mostly identical to the one on the axp20x pmics. One significant difference is that it cannot measure / monitor the usb voltage / current. Signed-off-by: Hans de Goede Acked-by: Rob Herring Signed-off-by: Sebastian Reichel --- .../bindings/power_supply/axp20x_usb_power.txt | 3 +- drivers/power/axp20x_usb_power.c | 92 ++++++++++++++++------ 2 files changed, 71 insertions(+), 24 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt b/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt index 862f4a49dc49..f1d7beec45bf 100644 --- a/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt +++ b/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt @@ -1,7 +1,8 @@ AXP20x USB power supply Required Properties: --compatible: "x-powers,axp202-usb-power-supply" +-compatible: One of: "x-powers,axp202-usb-power-supply" + "x-powers,axp221-usb-power-supply" This node is a subnode of the axp20x PMIC. diff --git a/drivers/power/axp20x_usb_power.c b/drivers/power/axp20x_usb_power.c index 421a90b83567..6af6feb7058d 100644 --- a/drivers/power/axp20x_usb_power.c +++ b/drivers/power/axp20x_usb_power.c @@ -42,6 +42,7 @@ #define AXP20X_VBUS_MON_VBUS_VALID BIT(3) struct axp20x_usb_power { + struct device_node *np; struct regmap *regmap; struct power_supply *supply; }; @@ -85,7 +86,12 @@ static int axp20x_usb_power_get_property(struct power_supply *psy, switch (v & AXP20X_VBUS_CLIMIT_MASK) { case AXP20X_VBUC_CLIMIT_100mA: - val->intval = 100000; + if (of_device_is_compatible(power->np, + "x-powers,axp202-usb-power-supply")) { + val->intval = 100000; + } else { + val->intval = -1; /* No 100mA limit */ + } break; case AXP20X_VBUC_CLIMIT_500mA: val->intval = 500000; @@ -122,16 +128,19 @@ static int axp20x_usb_power_get_property(struct power_supply *psy, break; } - ret = regmap_read(power->regmap, AXP20X_USB_OTG_STATUS, &v); - if (ret) - return ret; + val->intval = POWER_SUPPLY_HEALTH_GOOD; - if (!(v & AXP20X_USB_STATUS_VBUS_VALID)) { - val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; - break; - } + if (of_device_is_compatible(power->np, + "x-powers,axp202-usb-power-supply")) { + ret = regmap_read(power->regmap, + AXP20X_USB_OTG_STATUS, &v); + if (ret) + return ret; - val->intval = POWER_SUPPLY_HEALTH_GOOD; + if (!(v & AXP20X_USB_STATUS_VBUS_VALID)) + val->intval = + POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + } break; case POWER_SUPPLY_PROP_PRESENT: val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT); @@ -156,6 +165,14 @@ static enum power_supply_property axp20x_usb_power_properties[] = { POWER_SUPPLY_PROP_CURRENT_NOW, }; +static enum power_supply_property axp22x_usb_power_properties[] = { + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_MIN, + POWER_SUPPLY_PROP_CURRENT_MAX, +}; + static const struct power_supply_desc axp20x_usb_power_desc = { .name = "axp20x-usb", .type = POWER_SUPPLY_TYPE_USB, @@ -164,13 +181,25 @@ static const struct power_supply_desc axp20x_usb_power_desc = { .get_property = axp20x_usb_power_get_property, }; +static const struct power_supply_desc axp22x_usb_power_desc = { + .name = "axp20x-usb", + .type = POWER_SUPPLY_TYPE_USB, + .properties = axp22x_usb_power_properties, + .num_properties = ARRAY_SIZE(axp22x_usb_power_properties), + .get_property = axp20x_usb_power_get_property, +}; + static int axp20x_usb_power_probe(struct platform_device *pdev) { struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct power_supply_config psy_cfg = {}; struct axp20x_usb_power *power; - static const char * const irq_names[] = { "VBUS_PLUGIN", - "VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID" }; + static const char * const axp20x_irq_names[] = { "VBUS_PLUGIN", + "VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID", NULL }; + static const char * const axp22x_irq_names[] = { + "VBUS_PLUGIN", "VBUS_REMOVAL", NULL }; + static const char * const *irq_names; + const struct power_supply_desc *usb_power_desc; int i, irq, ret; if (!of_device_is_available(pdev->dev.of_node)) @@ -185,31 +214,47 @@ static int axp20x_usb_power_probe(struct platform_device *pdev) if (!power) return -ENOMEM; + power->np = pdev->dev.of_node; power->regmap = axp20x->regmap; - /* Enable vbus valid checking */ - ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON, - AXP20X_VBUS_MON_VBUS_VALID, AXP20X_VBUS_MON_VBUS_VALID); - if (ret) - return ret; + if (of_device_is_compatible(power->np, + "x-powers,axp202-usb-power-supply")) { + /* Enable vbus valid checking */ + ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON, + AXP20X_VBUS_MON_VBUS_VALID, + AXP20X_VBUS_MON_VBUS_VALID); + if (ret) + return ret; - /* Enable vbus voltage and current measurement */ - ret = regmap_update_bits(power->regmap, AXP20X_ADC_EN1, + /* Enable vbus voltage and current measurement */ + ret = regmap_update_bits(power->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT, AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT); - if (ret) - return ret; + if (ret) + return ret; + + usb_power_desc = &axp20x_usb_power_desc; + irq_names = axp20x_irq_names; + } else if (of_device_is_compatible(power->np, + "x-powers,axp221-usb-power-supply")) { + usb_power_desc = &axp22x_usb_power_desc; + irq_names = axp22x_irq_names; + } else { + dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", + axp20x->variant); + return -EINVAL; + } psy_cfg.of_node = pdev->dev.of_node; psy_cfg.drv_data = power; - power->supply = devm_power_supply_register(&pdev->dev, - &axp20x_usb_power_desc, &psy_cfg); + power->supply = devm_power_supply_register(&pdev->dev, usb_power_desc, + &psy_cfg); if (IS_ERR(power->supply)) return PTR_ERR(power->supply); /* Request irqs after registering, as irqs may trigger immediately */ - for (i = 0; i < ARRAY_SIZE(irq_names); i++) { + for (i = 0; irq_names[i]; i++) { irq = platform_get_irq_byname(pdev, irq_names[i]); if (irq < 0) { dev_warn(&pdev->dev, "No IRQ for %s: %d\n", @@ -229,6 +274,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev) static const struct of_device_id axp20x_usb_power_match[] = { { .compatible = "x-powers,axp202-usb-power-supply" }, + { .compatible = "x-powers,axp221-usb-power-supply" }, { } }; MODULE_DEVICE_TABLE(of, axp20x_usb_power_match); -- cgit v1.3-14-g43fede From 967dd82ffc52e9d8ea0defde094f9a39a3f4eeed Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 9 Jun 2016 18:23:53 -0700 Subject: net: dsa: b53: Add support for Broadcom RoboSwitch This patch adds support for Broadcom's BCM53xx switch family, also known as RoboSwitch. Some of these switches are ubiquituous, found in home routers, Wi-Fi routers, DSL and cable modem gateways and other networking related products. This drivers adds the library driver (b53_common.c) as well as a few bus glue drivers for MDIO, SPI, Switch Register Access Block (SRAB) and memory-mapped I/O into a SoC's address space (Broadcom BCM63xx/33xx). Basic operations are supported to bring the Layer 1/2 up and running, but not much more at this point, subsequent patches add the remaining features. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dsa/b53.txt | 88 ++ MAINTAINERS | 8 + drivers/net/dsa/Kconfig | 2 + drivers/net/dsa/Makefile | 2 + drivers/net/dsa/b53/Kconfig | 33 + drivers/net/dsa/b53/Makefile | 6 + drivers/net/dsa/b53/b53_common.c | 1158 +++++++++++++++++++++ drivers/net/dsa/b53/b53_mdio.c | 381 +++++++ drivers/net/dsa/b53/b53_mmap.c | 260 +++++ drivers/net/dsa/b53/b53_priv.h | 322 ++++++ drivers/net/dsa/b53/b53_regs.h | 358 +++++++ drivers/net/dsa/b53/b53_spi.c | 331 ++++++ drivers/net/dsa/b53/b53_srab.c | 415 ++++++++ include/linux/platform_data/b53.h | 33 + 14 files changed, 3397 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/dsa/b53.txt create mode 100644 drivers/net/dsa/b53/Kconfig create mode 100644 drivers/net/dsa/b53/Makefile create mode 100644 drivers/net/dsa/b53/b53_common.c create mode 100644 drivers/net/dsa/b53/b53_mdio.c create mode 100644 drivers/net/dsa/b53/b53_mmap.c create mode 100644 drivers/net/dsa/b53/b53_priv.h create mode 100644 drivers/net/dsa/b53/b53_regs.h create mode 100644 drivers/net/dsa/b53/b53_spi.c create mode 100644 drivers/net/dsa/b53/b53_srab.c create mode 100644 include/linux/platform_data/b53.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt new file mode 100644 index 000000000000..ca752db14dff --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/b53.txt @@ -0,0 +1,88 @@ +Broadcom BCM53xx Ethernet switches +================================== + +Required properties: + +- compatible: For external switch chips, compatible string must be exactly one + of: "brcm,bcm5325" + "brcm,bcm53115" + "brcm,bcm53125" + "brcm,bcm53128" + "brcm,bcm5365" + "brcm,bcm5395" + "brcm,bcm5397" + "brcm,bcm5398" + + For the BCM5310x SoCs with an integrated switch, must be one of: + "brcm,bcm53010-srab" + "brcm,bcm53011-srab" + "brcm,bcm53012-srab" + "brcm,bcm53018-srab" + "brcm,bcm53019-srab" and the mandatory "brcm,bcm5301x-srab" string + + For the BCM63xx/33xx SoCs with an integrated switch, must be one of: + "brcm,bcm3384-switch" + "brcm,bcm6328-switch" + "brcm,bcm6368-switch" and the mandatory "brcm,bcm63xx-switch" + +See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional +required and optional properties. + +Examples: + +Ethernet switch connected via MDIO to the host, CPU port wired to eth0: + + eth0: ethernet@10001000 { + compatible = "brcm,unimac"; + reg = <0x10001000 0x1000>; + + fixed-link { + speed = <1000>; + duplex-full; + }; + }; + + mdio0: mdio@10000000 { + compatible = "brcm,unimac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + switch0: ethernet-switch@30 { + compatible = "brcm,bcm53125"; + #address-cells = <1>; + #size-cells = <0>; + + ports { + port0@0 { + reg = <0>; + label = "lan1"; + }; + + port1@1 { + reg = <1>; + label = "lan2"; + }; + + port5@5 { + reg = <5>; + label = "cable-modem"; + fixed-link { + speed = <1000>; + duplex-full; + }; + phy-mode = "rgmii-txid"; + }; + + port8@8 { + reg = <8>; + label = "cpu"; + fixed-link { + speed = <1000>; + duplex-full; + }; + phy-mode = "rgmii-txid"; + ethernet = <ð0>; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 16e1500d7c52..b29a08884eed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2454,6 +2454,14 @@ L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/broadcom/b44.* +BROADCOM B53 ETHERNET SWITCH DRIVER +M: Florian Fainelli +L: netdev@vger.kernel.org +L: openwrt-devel@lists.openwrt.org (subscribers-only) +S: Supported +F: drivers/net/dsa/b53/* +F: include/linux/platform_data/b53.h + BROADCOM GENET ETHERNET DRIVER M: Florian Fainelli L: netdev@vger.kernel.org diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 200663c43ce9..be481e15ec9b 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -28,4 +28,6 @@ config NET_DSA_BCM_SF2 This enables support for the Broadcom Starfighter 2 Ethernet switch chips. +source "drivers/net/dsa/b53/Kconfig" + endmenu diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index 76b751dd9efd..97bc70a7f3c7 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -1,3 +1,5 @@ obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o + +obj-y += b53/ diff --git a/drivers/net/dsa/b53/Kconfig b/drivers/net/dsa/b53/Kconfig new file mode 100644 index 000000000000..27f32a50df57 --- /dev/null +++ b/drivers/net/dsa/b53/Kconfig @@ -0,0 +1,33 @@ +menuconfig B53 + tristate "Broadcom BCM53xx managed switch support" + depends on NET_DSA + help + This driver adds support for Broadcom managed switch chips. It supports + BCM5325E, BCM5365, BCM539x, BCM53115 and BCM53125 as well as BCM63XX + integrated switches. + +config B53_SPI_DRIVER + tristate "B53 SPI connected switch driver" + depends on B53 && SPI + help + Select to enable support for registering switches configured through SPI. + +config B53_MDIO_DRIVER + tristate "B53 MDIO connected switch driver" + depends on B53 + help + Select to enable support for registering switches configured through MDIO. + +config B53_MMAP_DRIVER + tristate "B53 MMAP connected switch driver" + depends on B53 && HAS_IOMEM + help + Select to enable support for memory-mapped switches like the BCM63XX + integrated switches. + +config B53_SRAB_DRIVER + tristate "B53 SRAB connected switch driver" + depends on B53 && HAS_IOMEM + help + Select to enable support for memory-mapped Switch Register Access + Bridge Registers (SRAB) like it is found on the BCM53010 diff --git a/drivers/net/dsa/b53/Makefile b/drivers/net/dsa/b53/Makefile new file mode 100644 index 000000000000..7e6f9a8bfd75 --- /dev/null +++ b/drivers/net/dsa/b53/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_B53) += b53_common.o + +obj-$(CONFIG_B53_SPI_DRIVER) += b53_spi.o +obj-$(CONFIG_B53_MDIO_DRIVER) += b53_mdio.o +obj-$(CONFIG_B53_MMAP_DRIVER) += b53_mmap.o +obj-$(CONFIG_B53_SRAB_DRIVER) += b53_srab.o diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c new file mode 100644 index 000000000000..6f0337d6dfa4 --- /dev/null +++ b/drivers/net/dsa/b53/b53_common.c @@ -0,0 +1,1158 @@ +/* + * B53 switch driver main logic + * + * Copyright (C) 2011-2013 Jonas Gorski + * Copyright (C) 2016 Florian Fainelli + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b53_regs.h" +#include "b53_priv.h" + +struct b53_mib_desc { + u8 size; + u8 offset; + const char *name; +}; + +/* BCM5365 MIB counters */ +static const struct b53_mib_desc b53_mibs_65[] = { + { 8, 0x00, "TxOctets" }, + { 4, 0x08, "TxDropPkts" }, + { 4, 0x10, "TxBroadcastPkts" }, + { 4, 0x14, "TxMulticastPkts" }, + { 4, 0x18, "TxUnicastPkts" }, + { 4, 0x1c, "TxCollisions" }, + { 4, 0x20, "TxSingleCollision" }, + { 4, 0x24, "TxMultipleCollision" }, + { 4, 0x28, "TxDeferredTransmit" }, + { 4, 0x2c, "TxLateCollision" }, + { 4, 0x30, "TxExcessiveCollision" }, + { 4, 0x38, "TxPausePkts" }, + { 8, 0x44, "RxOctets" }, + { 4, 0x4c, "RxUndersizePkts" }, + { 4, 0x50, "RxPausePkts" }, + { 4, 0x54, "Pkts64Octets" }, + { 4, 0x58, "Pkts65to127Octets" }, + { 4, 0x5c, "Pkts128to255Octets" }, + { 4, 0x60, "Pkts256to511Octets" }, + { 4, 0x64, "Pkts512to1023Octets" }, + { 4, 0x68, "Pkts1024to1522Octets" }, + { 4, 0x6c, "RxOversizePkts" }, + { 4, 0x70, "RxJabbers" }, + { 4, 0x74, "RxAlignmentErrors" }, + { 4, 0x78, "RxFCSErrors" }, + { 8, 0x7c, "RxGoodOctets" }, + { 4, 0x84, "RxDropPkts" }, + { 4, 0x88, "RxUnicastPkts" }, + { 4, 0x8c, "RxMulticastPkts" }, + { 4, 0x90, "RxBroadcastPkts" }, + { 4, 0x94, "RxSAChanges" }, + { 4, 0x98, "RxFragments" }, +}; + +#define B53_MIBS_65_SIZE ARRAY_SIZE(b53_mibs_65) + +/* BCM63xx MIB counters */ +static const struct b53_mib_desc b53_mibs_63xx[] = { + { 8, 0x00, "TxOctets" }, + { 4, 0x08, "TxDropPkts" }, + { 4, 0x0c, "TxQoSPkts" }, + { 4, 0x10, "TxBroadcastPkts" }, + { 4, 0x14, "TxMulticastPkts" }, + { 4, 0x18, "TxUnicastPkts" }, + { 4, 0x1c, "TxCollisions" }, + { 4, 0x20, "TxSingleCollision" }, + { 4, 0x24, "TxMultipleCollision" }, + { 4, 0x28, "TxDeferredTransmit" }, + { 4, 0x2c, "TxLateCollision" }, + { 4, 0x30, "TxExcessiveCollision" }, + { 4, 0x38, "TxPausePkts" }, + { 8, 0x3c, "TxQoSOctets" }, + { 8, 0x44, "RxOctets" }, + { 4, 0x4c, "RxUndersizePkts" }, + { 4, 0x50, "RxPausePkts" }, + { 4, 0x54, "Pkts64Octets" }, + { 4, 0x58, "Pkts65to127Octets" }, + { 4, 0x5c, "Pkts128to255Octets" }, + { 4, 0x60, "Pkts256to511Octets" }, + { 4, 0x64, "Pkts512to1023Octets" }, + { 4, 0x68, "Pkts1024to1522Octets" }, + { 4, 0x6c, "RxOversizePkts" }, + { 4, 0x70, "RxJabbers" }, + { 4, 0x74, "RxAlignmentErrors" }, + { 4, 0x78, "RxFCSErrors" }, + { 8, 0x7c, "RxGoodOctets" }, + { 4, 0x84, "RxDropPkts" }, + { 4, 0x88, "RxUnicastPkts" }, + { 4, 0x8c, "RxMulticastPkts" }, + { 4, 0x90, "RxBroadcastPkts" }, + { 4, 0x94, "RxSAChanges" }, + { 4, 0x98, "RxFragments" }, + { 4, 0xa0, "RxSymbolErrors" }, + { 4, 0xa4, "RxQoSPkts" }, + { 8, 0xa8, "RxQoSOctets" }, + { 4, 0xb0, "Pkts1523to2047Octets" }, + { 4, 0xb4, "Pkts2048to4095Octets" }, + { 4, 0xb8, "Pkts4096to8191Octets" }, + { 4, 0xbc, "Pkts8192to9728Octets" }, + { 4, 0xc0, "RxDiscarded" }, +}; + +#define B53_MIBS_63XX_SIZE ARRAY_SIZE(b53_mibs_63xx) + +/* MIB counters */ +static const struct b53_mib_desc b53_mibs[] = { + { 8, 0x00, "TxOctets" }, + { 4, 0x08, "TxDropPkts" }, + { 4, 0x10, "TxBroadcastPkts" }, + { 4, 0x14, "TxMulticastPkts" }, + { 4, 0x18, "TxUnicastPkts" }, + { 4, 0x1c, "TxCollisions" }, + { 4, 0x20, "TxSingleCollision" }, + { 4, 0x24, "TxMultipleCollision" }, + { 4, 0x28, "TxDeferredTransmit" }, + { 4, 0x2c, "TxLateCollision" }, + { 4, 0x30, "TxExcessiveCollision" }, + { 4, 0x38, "TxPausePkts" }, + { 8, 0x50, "RxOctets" }, + { 4, 0x58, "RxUndersizePkts" }, + { 4, 0x5c, "RxPausePkts" }, + { 4, 0x60, "Pkts64Octets" }, + { 4, 0x64, "Pkts65to127Octets" }, + { 4, 0x68, "Pkts128to255Octets" }, + { 4, 0x6c, "Pkts256to511Octets" }, + { 4, 0x70, "Pkts512to1023Octets" }, + { 4, 0x74, "Pkts1024to1522Octets" }, + { 4, 0x78, "RxOversizePkts" }, + { 4, 0x7c, "RxJabbers" }, + { 4, 0x80, "RxAlignmentErrors" }, + { 4, 0x84, "RxFCSErrors" }, + { 8, 0x88, "RxGoodOctets" }, + { 4, 0x90, "RxDropPkts" }, + { 4, 0x94, "RxUnicastPkts" }, + { 4, 0x98, "RxMulticastPkts" }, + { 4, 0x9c, "RxBroadcastPkts" }, + { 4, 0xa0, "RxSAChanges" }, + { 4, 0xa4, "RxFragments" }, + { 4, 0xa8, "RxJumboPkts" }, + { 4, 0xac, "RxSymbolErrors" }, + { 4, 0xc0, "RxDiscarded" }, +}; + +#define B53_MIBS_SIZE ARRAY_SIZE(b53_mibs) + +static int b53_do_vlan_op(struct b53_device *dev, u8 op) +{ + unsigned int i; + + b53_write8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], VTA_START_CMD | op); + + for (i = 0; i < 10; i++) { + u8 vta; + + b53_read8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], &vta); + if (!(vta & VTA_START_CMD)) + return 0; + + usleep_range(100, 200); + } + + return -EIO; +} + +static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, u16 members, + u16 untag) +{ + if (is5325(dev)) { + u32 entry = 0; + + if (members) { + entry = ((untag & VA_UNTAG_MASK_25) << VA_UNTAG_S_25) | + members; + if (dev->core_rev >= 3) + entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S; + else + entry |= VA_VALID_25; + } + + b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry); + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | + VTA_RW_STATE_WR | VTA_RW_OP_EN); + } else if (is5365(dev)) { + u16 entry = 0; + + if (members) + entry = ((untag & VA_UNTAG_MASK_65) << VA_UNTAG_S_65) | + members | VA_VALID_65; + + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, entry); + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | + VTA_RW_STATE_WR | VTA_RW_OP_EN); + } else { + b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); + b53_write32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], + (untag << VTE_UNTAG_S) | members); + + b53_do_vlan_op(dev, VTA_CMD_WRITE); + } +} + +void b53_set_forwarding(struct b53_device *dev, int enable) +{ + u8 mgmt; + + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); + + if (enable) + mgmt |= SM_SW_FWD_EN; + else + mgmt &= ~SM_SW_FWD_EN; + + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); +} + +static void b53_enable_vlan(struct b53_device *dev, int enable) +{ + u8 mgmt, vc0, vc1, vc4 = 0, vc5; + + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0); + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1); + + if (is5325(dev) || is5365(dev)) { + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, &vc5); + } else if (is63xx(dev)) { + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, &vc4); + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, &vc5); + } else { + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4); + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); + } + + mgmt &= ~SM_SW_FWD_MODE; + + if (enable) { + vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; + vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; + vc4 &= ~VC4_ING_VID_CHECK_MASK; + vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S; + vc5 |= VC5_DROP_VTABLE_MISS; + + if (is5325(dev)) + vc0 &= ~VC0_RESERVED_1; + + if (is5325(dev) || is5365(dev)) + vc1 |= VC1_RX_MCST_TAG_EN; + + if (!is5325(dev) && !is5365(dev)) { + if (dev->allow_vid_4095) + vc5 |= VC5_VID_FFF_EN; + else + vc5 &= ~VC5_VID_FFF_EN; + } + } else { + vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID); + vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN); + vc4 &= ~VC4_ING_VID_CHECK_MASK; + vc5 &= ~VC5_DROP_VTABLE_MISS; + + if (is5325(dev) || is5365(dev)) + vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; + else + vc4 |= VC4_ING_VID_VIO_TO_IMP << VC4_ING_VID_CHECK_S; + + if (is5325(dev) || is5365(dev)) + vc1 &= ~VC1_RX_MCST_TAG_EN; + + if (!is5325(dev) && !is5365(dev)) + vc5 &= ~VC5_VID_FFF_EN; + } + + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, vc0); + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, vc1); + + if (is5325(dev) || is5365(dev)) { + /* enable the high 8 bit vid check on 5325 */ + if (is5325(dev) && enable) + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, + VC3_HIGH_8BIT_EN); + else + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); + + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, vc4); + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, vc5); + } else if (is63xx(dev)) { + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3_63XX, 0); + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, vc4); + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, vc5); + } else { + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, vc4); + b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, vc5); + } + + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); +} + +static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100) +{ + u32 port_mask = 0; + u16 max_size = JMS_MIN_SIZE; + + if (is5325(dev) || is5365(dev)) + return -EINVAL; + + if (enable) { + port_mask = dev->enabled_ports; + max_size = JMS_MAX_SIZE; + if (allow_10_100) + port_mask |= JPM_10_100_JUMBO_EN; + } + + b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask); + return b53_write16(dev, B53_JUMBO_PAGE, dev->jumbo_size_reg, max_size); +} + +static int b53_flush_arl(struct b53_device *dev) +{ + unsigned int i; + + b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, + FAST_AGE_DONE | FAST_AGE_DYNAMIC | FAST_AGE_STATIC); + + for (i = 0; i < 10; i++) { + u8 fast_age_ctrl; + + b53_read8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, + &fast_age_ctrl); + + if (!(fast_age_ctrl & FAST_AGE_DONE)) + goto out; + + msleep(1); + } + + return -ETIMEDOUT; +out: + /* Only age dynamic entries (default behavior) */ + b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, FAST_AGE_DYNAMIC); + return 0; +} + +static int b53_enable_port(struct dsa_switch *ds, int port, + struct phy_device *phy) +{ + struct b53_device *dev = ds_to_priv(ds); + + /* Clear the Rx and Tx disable bits and set to no spanning tree */ + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), 0); + + return 0; +} + +static void b53_disable_port(struct dsa_switch *ds, int port, + struct phy_device *phy) +{ + struct b53_device *dev = ds_to_priv(ds); + u8 reg; + + /* Disable Tx/Rx for the port */ + b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); + reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); +} + +static void b53_enable_cpu_port(struct b53_device *dev) +{ + unsigned int cpu_port = dev->cpu_port; + u8 port_ctrl; + + /* BCM5325 CPU port is at 8 */ + if ((is5325(dev) || is5365(dev)) && cpu_port == B53_CPU_PORT_25) + cpu_port = B53_CPU_PORT; + + port_ctrl = PORT_CTRL_RX_BCST_EN | + PORT_CTRL_RX_MCST_EN | + PORT_CTRL_RX_UCST_EN; + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(cpu_port), port_ctrl); +} + +static void b53_enable_mib(struct b53_device *dev) +{ + u8 gc; + + b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc); + gc &= ~(GC_RESET_MIB | GC_MIB_AC_EN); + b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); +} + +static int b53_configure_vlan(struct b53_device *dev) +{ + int i; + + /* clear all vlan entries */ + if (is5325(dev) || is5365(dev)) { + for (i = 1; i < dev->num_vlans; i++) + b53_set_vlan_entry(dev, i, 0, 0); + } else { + b53_do_vlan_op(dev, VTA_CMD_CLEAR); + } + + b53_enable_vlan(dev, false); + + b53_for_each_port(dev, i) + b53_write16(dev, B53_VLAN_PAGE, + B53_VLAN_PORT_DEF_TAG(i), 1); + + if (!is5325(dev) && !is5365(dev)) + b53_set_jumbo(dev, dev->enable_jumbo, false); + + return 0; +} + +static void b53_switch_reset_gpio(struct b53_device *dev) +{ + int gpio = dev->reset_gpio; + + if (gpio < 0) + return; + + /* Reset sequence: RESET low(50ms)->high(20ms) + */ + gpio_set_value(gpio, 0); + mdelay(50); + + gpio_set_value(gpio, 1); + mdelay(20); + + dev->current_page = 0xff; +} + +static int b53_switch_reset(struct b53_device *dev) +{ + u8 mgmt; + + b53_switch_reset_gpio(dev); + + if (is539x(dev)) { + b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x83); + b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x00); + } + + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); + + if (!(mgmt & SM_SW_FWD_EN)) { + mgmt &= ~SM_SW_FWD_MODE; + mgmt |= SM_SW_FWD_EN; + + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); + + if (!(mgmt & SM_SW_FWD_EN)) { + dev_err(dev->dev, "Failed to enable switch!\n"); + return -EINVAL; + } + } + + b53_enable_mib(dev); + + return b53_flush_arl(dev); +} + +static int b53_phy_read16(struct dsa_switch *ds, int addr, int reg) +{ + struct b53_device *priv = ds_to_priv(ds); + u16 value = 0; + int ret; + + if (priv->ops->phy_read16) + ret = priv->ops->phy_read16(priv, addr, reg, &value); + else + ret = b53_read16(priv, B53_PORT_MII_PAGE(addr), + reg * 2, &value); + + return ret ? ret : value; +} + +static int b53_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val) +{ + struct b53_device *priv = ds_to_priv(ds); + + if (priv->ops->phy_write16) + return priv->ops->phy_write16(priv, addr, reg, val); + + return b53_write16(priv, B53_PORT_MII_PAGE(addr), reg * 2, val); +} + +static int b53_reset_switch(struct b53_device *priv) +{ + /* reset vlans */ + priv->enable_jumbo = false; + + memset(priv->ports, 0, sizeof(*priv->ports) * priv->num_ports); + + return b53_switch_reset(priv); +} + +static int b53_apply_config(struct b53_device *priv) +{ + /* disable switching */ + b53_set_forwarding(priv, 0); + + b53_configure_vlan(priv); + + /* enable switching */ + b53_set_forwarding(priv, 1); + + return 0; +} + +static void b53_reset_mib(struct b53_device *priv) +{ + u8 gc; + + b53_read8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc); + + b53_write8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc | GC_RESET_MIB); + msleep(1); + b53_write8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc & ~GC_RESET_MIB); + msleep(1); +} + +static const struct b53_mib_desc *b53_get_mib(struct b53_device *dev) +{ + if (is5365(dev)) + return b53_mibs_65; + else if (is63xx(dev)) + return b53_mibs_63xx; + else + return b53_mibs; +} + +static unsigned int b53_get_mib_size(struct b53_device *dev) +{ + if (is5365(dev)) + return B53_MIBS_65_SIZE; + else if (is63xx(dev)) + return B53_MIBS_63XX_SIZE; + else + return B53_MIBS_SIZE; +} + +static void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data) +{ + struct b53_device *dev = ds_to_priv(ds); + const struct b53_mib_desc *mibs = b53_get_mib(dev); + unsigned int mib_size = b53_get_mib_size(dev); + unsigned int i; + + for (i = 0; i < mib_size; i++) + memcpy(data + i * ETH_GSTRING_LEN, + mibs[i].name, ETH_GSTRING_LEN); +} + +static void b53_get_ethtool_stats(struct dsa_switch *ds, int port, + uint64_t *data) +{ + struct b53_device *dev = ds_to_priv(ds); + const struct b53_mib_desc *mibs = b53_get_mib(dev); + unsigned int mib_size = b53_get_mib_size(dev); + const struct b53_mib_desc *s; + unsigned int i; + u64 val = 0; + + if (is5365(dev) && port == 5) + port = 8; + + mutex_lock(&dev->stats_mutex); + + for (i = 0; i < mib_size; i++) { + s = &mibs[i]; + + if (mibs->size == 8) { + b53_read64(dev, B53_MIB_PAGE(port), s->offset, &val); + } else { + u32 val32; + + b53_read32(dev, B53_MIB_PAGE(port), s->offset, + &val32); + val = val32; + } + data[i] = (u64)val; + } + + mutex_unlock(&dev->stats_mutex); +} + +static int b53_get_sset_count(struct dsa_switch *ds) +{ + struct b53_device *dev = ds_to_priv(ds); + + return b53_get_mib_size(dev); +} + +static int b53_set_addr(struct dsa_switch *ds, u8 *addr) +{ + return 0; +} + +static int b53_setup(struct dsa_switch *ds) +{ + struct b53_device *dev = ds_to_priv(ds); + unsigned int port; + int ret; + + ret = b53_reset_switch(dev); + if (ret) { + dev_err(ds->dev, "failed to reset switch\n"); + return ret; + } + + b53_reset_mib(dev); + + ret = b53_apply_config(dev); + if (ret) + dev_err(ds->dev, "failed to apply configuration\n"); + + for (port = 0; port < dev->num_ports; port++) { + if (BIT(port) & ds->enabled_port_mask) + b53_enable_port(ds, port, NULL); + else if (dsa_is_cpu_port(ds, port)) + b53_enable_cpu_port(dev); + else + b53_disable_port(ds, port, NULL); + } + + return ret; +} + +static void b53_adjust_link(struct dsa_switch *ds, int port, + struct phy_device *phydev) +{ + struct b53_device *dev = ds_to_priv(ds); + u8 rgmii_ctrl = 0, reg = 0, off; + + if (!phy_is_pseudo_fixed_link(phydev)) + return; + + /* Override the port settings */ + if (port == dev->cpu_port) { + off = B53_PORT_OVERRIDE_CTRL; + reg = PORT_OVERRIDE_EN; + } else { + off = B53_GMII_PORT_OVERRIDE_CTRL(port); + reg = GMII_PO_EN; + } + + /* Set the link UP */ + if (phydev->link) + reg |= PORT_OVERRIDE_LINK; + + if (phydev->duplex == DUPLEX_FULL) + reg |= PORT_OVERRIDE_FULL_DUPLEX; + + switch (phydev->speed) { + case 2000: + reg |= PORT_OVERRIDE_SPEED_2000M; + /* fallthrough */ + case SPEED_1000: + reg |= PORT_OVERRIDE_SPEED_1000M; + break; + case SPEED_100: + reg |= PORT_OVERRIDE_SPEED_100M; + break; + case SPEED_10: + reg |= PORT_OVERRIDE_SPEED_10M; + break; + default: + dev_err(ds->dev, "unknown speed: %d\n", phydev->speed); + return; + } + + /* Enable flow control on BCM5301x's CPU port */ + if (is5301x(dev) && port == dev->cpu_port) + reg |= PORT_OVERRIDE_RX_FLOW | PORT_OVERRIDE_TX_FLOW; + + if (phydev->pause) { + if (phydev->asym_pause) + reg |= PORT_OVERRIDE_TX_FLOW; + reg |= PORT_OVERRIDE_RX_FLOW; + } + + b53_write8(dev, B53_CTRL_PAGE, off, reg); + + if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { + if (port == 8) + off = B53_RGMII_CTRL_IMP; + else + off = B53_RGMII_CTRL_P(port); + + /* Configure the port RGMII clock delay by DLL disabled and + * tx_clk aligned timing (restoring to reset defaults) + */ + b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); + rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC | + RGMII_CTRL_TIMING_SEL); + + /* PHY_INTERFACE_MODE_RGMII_TXID means TX internal delay, make + * sure that we enable the port TX clock internal delay to + * account for this internal delay that is inserted, otherwise + * the switch won't be able to receive correctly. + * + * PHY_INTERFACE_MODE_RGMII means that we are not introducing + * any delay neither on transmission nor reception, so the + * BCM53125 must also be configured accordingly to account for + * the lack of delay and introduce + * + * The BCM53125 switch has its RX clock and TX clock control + * swapped, hence the reason why we modify the TX clock path in + * the "RGMII" case + */ + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + rgmii_ctrl |= RGMII_CTRL_DLL_TXC; + if (phydev->interface == PHY_INTERFACE_MODE_RGMII) + rgmii_ctrl |= RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC; + rgmii_ctrl |= RGMII_CTRL_TIMING_SEL; + b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); + + dev_info(ds->dev, "Configured port %d for %s\n", port, + phy_modes(phydev->interface)); + } + + /* configure MII port if necessary */ + if (is5325(dev)) { + b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, + ®); + + /* reverse mii needs to be enabled */ + if (!(reg & PORT_OVERRIDE_RV_MII_25)) { + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, + reg | PORT_OVERRIDE_RV_MII_25); + b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, + ®); + + if (!(reg & PORT_OVERRIDE_RV_MII_25)) { + dev_err(ds->dev, + "Failed to enable reverse MII mode\n"); + return; + } + } + } else if (is5301x(dev)) { + if (port != dev->cpu_port) { + u8 po_reg = B53_GMII_PORT_OVERRIDE_CTRL(dev->cpu_port); + u8 gmii_po; + + b53_read8(dev, B53_CTRL_PAGE, po_reg, &gmii_po); + gmii_po |= GMII_PO_LINK | + GMII_PO_RX_FLOW | + GMII_PO_TX_FLOW | + GMII_PO_EN | + GMII_PO_SPEED_2000M; + b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po); + } + } +} + +static struct dsa_switch_driver b53_switch_ops = { + .tag_protocol = DSA_TAG_PROTO_NONE, + .setup = b53_setup, + .set_addr = b53_set_addr, + .get_strings = b53_get_strings, + .get_ethtool_stats = b53_get_ethtool_stats, + .get_sset_count = b53_get_sset_count, + .phy_read = b53_phy_read16, + .phy_write = b53_phy_write16, + .adjust_link = b53_adjust_link, + .port_enable = b53_enable_port, + .port_disable = b53_disable_port, +}; + +struct b53_chip_data { + u32 chip_id; + const char *dev_name; + u16 vlans; + u16 enabled_ports; + u8 cpu_port; + u8 vta_regs[3]; + u8 duplex_reg; + u8 jumbo_pm_reg; + u8 jumbo_size_reg; +}; + +#define B53_VTA_REGS \ + { B53_VT_ACCESS, B53_VT_INDEX, B53_VT_ENTRY } +#define B53_VTA_REGS_9798 \ + { B53_VT_ACCESS_9798, B53_VT_INDEX_9798, B53_VT_ENTRY_9798 } +#define B53_VTA_REGS_63XX \ + { B53_VT_ACCESS_63XX, B53_VT_INDEX_63XX, B53_VT_ENTRY_63XX } + +static const struct b53_chip_data b53_switch_chips[] = { + { + .chip_id = BCM5325_DEVICE_ID, + .dev_name = "BCM5325", + .vlans = 16, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT_25, + .duplex_reg = B53_DUPLEX_STAT_FE, + }, + { + .chip_id = BCM5365_DEVICE_ID, + .dev_name = "BCM5365", + .vlans = 256, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT_25, + .duplex_reg = B53_DUPLEX_STAT_FE, + }, + { + .chip_id = BCM5395_DEVICE_ID, + .dev_name = "BCM5395", + .vlans = 4096, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT, + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM5397_DEVICE_ID, + .dev_name = "BCM5397", + .vlans = 4096, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT, + .vta_regs = B53_VTA_REGS_9798, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM5398_DEVICE_ID, + .dev_name = "BCM5398", + .vlans = 4096, + .enabled_ports = 0x7f, + .cpu_port = B53_CPU_PORT, + .vta_regs = B53_VTA_REGS_9798, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53115_DEVICE_ID, + .dev_name = "BCM53115", + .vlans = 4096, + .enabled_ports = 0x1f, + .vta_regs = B53_VTA_REGS, + .cpu_port = B53_CPU_PORT, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53125_DEVICE_ID, + .dev_name = "BCM53125", + .vlans = 4096, + .enabled_ports = 0xff, + .cpu_port = B53_CPU_PORT, + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53128_DEVICE_ID, + .dev_name = "BCM53128", + .vlans = 4096, + .enabled_ports = 0x1ff, + .cpu_port = B53_CPU_PORT, + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM63XX_DEVICE_ID, + .dev_name = "BCM63xx", + .vlans = 4096, + .enabled_ports = 0, /* pdata must provide them */ + .cpu_port = B53_CPU_PORT, + .vta_regs = B53_VTA_REGS_63XX, + .duplex_reg = B53_DUPLEX_STAT_63XX, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, + }, + { + .chip_id = BCM53010_DEVICE_ID, + .dev_name = "BCM53010", + .vlans = 4096, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53011_DEVICE_ID, + .dev_name = "BCM53011", + .vlans = 4096, + .enabled_ports = 0x1bf, + .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53012_DEVICE_ID, + .dev_name = "BCM53012", + .vlans = 4096, + .enabled_ports = 0x1bf, + .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53018_DEVICE_ID, + .dev_name = "BCM53018", + .vlans = 4096, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, + { + .chip_id = BCM53019_DEVICE_ID, + .dev_name = "BCM53019", + .vlans = 4096, + .enabled_ports = 0x1f, + .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ + .vta_regs = B53_VTA_REGS, + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, +}; + +static int b53_switch_init(struct b53_device *dev) +{ + struct dsa_switch *ds = dev->ds; + unsigned int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) { + const struct b53_chip_data *chip = &b53_switch_chips[i]; + + if (chip->chip_id == dev->chip_id) { + if (!dev->enabled_ports) + dev->enabled_ports = chip->enabled_ports; + dev->name = chip->dev_name; + dev->duplex_reg = chip->duplex_reg; + dev->vta_regs[0] = chip->vta_regs[0]; + dev->vta_regs[1] = chip->vta_regs[1]; + dev->vta_regs[2] = chip->vta_regs[2]; + dev->jumbo_pm_reg = chip->jumbo_pm_reg; + ds->drv = &b53_switch_ops; + dev->cpu_port = chip->cpu_port; + dev->num_vlans = chip->vlans; + break; + } + } + + /* check which BCM5325x version we have */ + if (is5325(dev)) { + u8 vc4; + + b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); + + /* check reserved bits */ + switch (vc4 & 3) { + case 1: + /* BCM5325E */ + break; + case 3: + /* BCM5325F - do not use port 4 */ + dev->enabled_ports &= ~BIT(4); + break; + default: +/* On the BCM47XX SoCs this is the supported internal switch.*/ +#ifndef CONFIG_BCM47XX + /* BCM5325M */ + return -EINVAL; +#else + break; +#endif + } + } else if (dev->chip_id == BCM53115_DEVICE_ID) { + u64 strap_value; + + b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); + /* use second IMP port if GMII is enabled */ + if (strap_value & SV_GMII_CTRL_115) + dev->cpu_port = 5; + } + + /* cpu port is always last */ + dev->num_ports = dev->cpu_port + 1; + dev->enabled_ports |= BIT(dev->cpu_port); + + dev->ports = devm_kzalloc(dev->dev, + sizeof(struct b53_port) * dev->num_ports, + GFP_KERNEL); + if (!dev->ports) + return -ENOMEM; + + dev->reset_gpio = b53_switch_get_reset_gpio(dev); + if (dev->reset_gpio >= 0) { + ret = devm_gpio_request_one(dev->dev, dev->reset_gpio, + GPIOF_OUT_INIT_HIGH, "robo_reset"); + if (ret) + return ret; + } + + return 0; +} + +struct b53_device *b53_switch_alloc(struct device *base, struct b53_io_ops *ops, + void *priv) +{ + struct dsa_switch *ds; + struct b53_device *dev; + + ds = devm_kzalloc(base, sizeof(*ds) + sizeof(*dev), GFP_KERNEL); + if (!ds) + return NULL; + + dev = (struct b53_device *)(ds + 1); + + ds->priv = dev; + ds->dev = base; + dev->dev = base; + + dev->ds = ds; + dev->priv = priv; + dev->ops = ops; + mutex_init(&dev->reg_mutex); + mutex_init(&dev->stats_mutex); + + return dev; +} +EXPORT_SYMBOL(b53_switch_alloc); + +int b53_switch_detect(struct b53_device *dev) +{ + u32 id32; + u16 tmp; + u8 id8; + int ret; + + ret = b53_read8(dev, B53_MGMT_PAGE, B53_DEVICE_ID, &id8); + if (ret) + return ret; + + switch (id8) { + case 0: + /* BCM5325 and BCM5365 do not have this register so reads + * return 0. But the read operation did succeed, so assume this + * is one of them. + * + * Next check if we can write to the 5325's VTA register; for + * 5365 it is read only. + */ + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, 0xf); + b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, &tmp); + + if (tmp == 0xf) + dev->chip_id = BCM5325_DEVICE_ID; + else + dev->chip_id = BCM5365_DEVICE_ID; + break; + case BCM5395_DEVICE_ID: + case BCM5397_DEVICE_ID: + case BCM5398_DEVICE_ID: + dev->chip_id = id8; + break; + default: + ret = b53_read32(dev, B53_MGMT_PAGE, B53_DEVICE_ID, &id32); + if (ret) + return ret; + + switch (id32) { + case BCM53115_DEVICE_ID: + case BCM53125_DEVICE_ID: + case BCM53128_DEVICE_ID: + case BCM53010_DEVICE_ID: + case BCM53011_DEVICE_ID: + case BCM53012_DEVICE_ID: + case BCM53018_DEVICE_ID: + case BCM53019_DEVICE_ID: + dev->chip_id = id32; + break; + default: + pr_err("unsupported switch detected (BCM53%02x/BCM%x)\n", + id8, id32); + return -ENODEV; + } + } + + if (dev->chip_id == BCM5325_DEVICE_ID) + return b53_read8(dev, B53_STAT_PAGE, B53_REV_ID_25, + &dev->core_rev); + else + return b53_read8(dev, B53_MGMT_PAGE, B53_REV_ID, + &dev->core_rev); +} +EXPORT_SYMBOL(b53_switch_detect); + +int b53_switch_register(struct b53_device *dev) +{ + int ret; + + if (dev->pdata) { + dev->chip_id = dev->pdata->chip_id; + dev->enabled_ports = dev->pdata->enabled_ports; + } + + if (!dev->chip_id && b53_switch_detect(dev)) + return -EINVAL; + + ret = b53_switch_init(dev); + if (ret) + return ret; + + pr_info("found switch: %s, rev %i\n", dev->name, dev->core_rev); + + return dsa_register_switch(dev->ds, dev->ds->dev->of_node); +} +EXPORT_SYMBOL(b53_switch_register); + +MODULE_AUTHOR("Jonas Gorski "); +MODULE_DESCRIPTION("B53 switch library"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/dsa/b53/b53_mdio.c b/drivers/net/dsa/b53/b53_mdio.c new file mode 100644 index 000000000000..c6cf7cf57cc3 --- /dev/null +++ b/drivers/net/dsa/b53/b53_mdio.c @@ -0,0 +1,381 @@ +/* + * B53 register access through MII registers + * + * Copyright (C) 2011-2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "b53_priv.h" + +/* MII registers */ +#define REG_MII_PAGE 0x10 /* MII Page register */ +#define REG_MII_ADDR 0x11 /* MII Address register */ +#define REG_MII_DATA0 0x18 /* MII Data register 0 */ +#define REG_MII_DATA1 0x19 /* MII Data register 1 */ +#define REG_MII_DATA2 0x1a /* MII Data register 2 */ +#define REG_MII_DATA3 0x1b /* MII Data register 3 */ + +#define REG_MII_PAGE_ENABLE BIT(0) +#define REG_MII_ADDR_WRITE BIT(0) +#define REG_MII_ADDR_READ BIT(1) + +static int b53_mdio_op(struct b53_device *dev, u8 page, u8 reg, u16 op) +{ + int i; + u16 v; + int ret; + struct mii_bus *bus = dev->priv; + + if (dev->current_page != page) { + /* set page number */ + v = (page << 8) | REG_MII_PAGE_ENABLE; + ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_PAGE, v); + if (ret) + return ret; + dev->current_page = page; + } + + /* set register address */ + v = (reg << 8) | op; + ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, REG_MII_ADDR, v); + if (ret) + return ret; + + /* check if operation completed */ + for (i = 0; i < 5; ++i) { + v = mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_ADDR); + if (!(v & (REG_MII_ADDR_WRITE | REG_MII_ADDR_READ))) + break; + usleep_range(10, 100); + } + + if (WARN_ON(i == 5)) + return -EIO; + + return 0; +} + +static int b53_mdio_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) +{ + struct mii_bus *bus = dev->priv; + int ret; + + ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + *val = mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0) & 0xff; + + return 0; +} + +static int b53_mdio_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) +{ + struct mii_bus *bus = dev->priv; + int ret; + + ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + *val = mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, REG_MII_DATA0); + + return 0; +} + +static int b53_mdio_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) +{ + struct mii_bus *bus = dev->priv; + int ret; + + ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + *val = mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, REG_MII_DATA0); + *val |= mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA1) << 16; + + return 0; +} + +static int b53_mdio_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + struct mii_bus *bus = dev->priv; + u64 temp = 0; + int i; + int ret; + + ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + for (i = 2; i >= 0; i--) { + temp <<= 16; + temp |= mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0 + i); + } + + *val = temp; + + return 0; +} + +static int b53_mdio_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + struct mii_bus *bus = dev->priv; + u64 temp = 0; + int i; + int ret; + + ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + for (i = 3; i >= 0; i--) { + temp <<= 16; + temp |= mdiobus_read_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0 + i); + } + + *val = temp; + + return 0; +} + +static int b53_mdio_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) +{ + struct mii_bus *bus = dev->priv; + int ret; + + ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0, value); + if (ret) + return ret; + + return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write16(struct b53_device *dev, u8 page, u8 reg, + u16 value) +{ + struct mii_bus *bus = dev->priv; + int ret; + + ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0, value); + if (ret) + return ret; + + return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write32(struct b53_device *dev, u8 page, u8 reg, + u32 value) +{ + struct mii_bus *bus = dev->priv; + unsigned int i; + u32 temp = value; + + for (i = 0; i < 2; i++) { + int ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0 + i, + temp & 0xffff); + if (ret) + return ret; + temp >>= 16; + } + + return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write48(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + struct mii_bus *bus = dev->priv; + unsigned int i; + u64 temp = value; + + for (i = 0; i < 3; i++) { + int ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0 + i, + temp & 0xffff); + if (ret) + return ret; + temp >>= 16; + } + + return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write64(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + struct mii_bus *bus = dev->priv; + unsigned int i; + u64 temp = value; + + for (i = 0; i < 4; i++) { + int ret = mdiobus_write_nested(bus, BRCM_PSEUDO_PHY_ADDR, + REG_MII_DATA0 + i, + temp & 0xffff); + if (ret) + return ret; + temp >>= 16; + } + + return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_phy_read16(struct b53_device *dev, int addr, int reg, + u16 *value) +{ + struct mii_bus *bus = dev->priv; + + *value = mdiobus_read_nested(bus, addr, reg); + + return 0; +} + +static int b53_mdio_phy_write16(struct b53_device *dev, int addr, int reg, + u16 value) +{ + struct mii_bus *bus = dev->bus; + + return mdiobus_write_nested(bus, addr, reg, value); +} + +static struct b53_io_ops b53_mdio_ops = { + .read8 = b53_mdio_read8, + .read16 = b53_mdio_read16, + .read32 = b53_mdio_read32, + .read48 = b53_mdio_read48, + .read64 = b53_mdio_read64, + .write8 = b53_mdio_write8, + .write16 = b53_mdio_write16, + .write32 = b53_mdio_write32, + .write48 = b53_mdio_write48, + .write64 = b53_mdio_write64, + .phy_read16 = b53_mdio_phy_read16, + .phy_write16 = b53_mdio_phy_write16, +}; + +#define B53_BRCM_OUI_1 0x0143bc00 +#define B53_BRCM_OUI_2 0x03625c00 +#define B53_BRCM_OUI_3 0x00406000 + +static int b53_mdio_probe(struct mdio_device *mdiodev) +{ + struct b53_device *dev; + u32 phy_id; + int ret; + + /* allow the generic PHY driver to take over the non-management MDIO + * addresses + */ + if (mdiodev->addr != BRCM_PSEUDO_PHY_ADDR && mdiodev->addr != 0) { + dev_err(&mdiodev->dev, "leaving address %d to PHY\n", + mdiodev->addr); + return -ENODEV; + } + + /* read the first port's id */ + phy_id = mdiobus_read(mdiodev->bus, 0, 2) << 16; + phy_id |= mdiobus_read(mdiodev->bus, 0, 3); + + /* BCM5325, BCM539x (OUI_1) + * BCM53125, BCM53128 (OUI_2) + * BCM5365 (OUI_3) + */ + if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 && + (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 && + (phy_id & 0xfffffc00) != B53_BRCM_OUI_3) { + dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id); + return -ENODEV; + } + + dev = b53_switch_alloc(&mdiodev->dev, &b53_mdio_ops, mdiodev->bus); + if (!dev) + return -ENOMEM; + + /* we don't use page 0xff, so force a page set */ + dev->current_page = 0xff; + dev->bus = mdiodev->bus; + + dev_set_drvdata(&mdiodev->dev, dev); + + ret = b53_switch_register(dev); + if (ret) { + dev_err(&mdiodev->dev, "failed to register switch: %i\n", ret); + return ret; + } + + return ret; +} + +static void b53_mdio_remove(struct mdio_device *mdiodev) +{ + struct b53_device *dev = dev_get_drvdata(&mdiodev->dev); + struct dsa_switch *ds = dev->ds; + + dsa_unregister_switch(ds); +} + +static const struct of_device_id b53_of_match[] = { + { .compatible = "brcm,bcm5325" }, + { .compatible = "brcm,bcm53115" }, + { .compatible = "brcm,bcm53125" }, + { .compatible = "brcm,bcm53128" }, + { .compatible = "brcm,bcm5365" }, + { .compatible = "brcm,bcm5395" }, + { .compatible = "brcm,bcm5397" }, + { .compatible = "brcm,bcm5398" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, b53_of_match); + +static struct mdio_driver b53_mdio_driver = { + .probe = b53_mdio_probe, + .remove = b53_mdio_remove, + .mdiodrv.driver = { + .name = "bcm53xx", + .of_match_table = b53_of_match, + }, +}; + +static int __init b53_mdio_driver_register(void) +{ + return mdio_driver_register(&b53_mdio_driver); +} +module_init(b53_mdio_driver_register); + +static void __exit b53_mdio_driver_unregister(void) +{ + mdio_driver_unregister(&b53_mdio_driver); +} +module_exit(b53_mdio_driver_unregister); + +MODULE_DESCRIPTION("B53 MDIO access driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/dsa/b53/b53_mmap.c b/drivers/net/dsa/b53/b53_mmap.c new file mode 100644 index 000000000000..f115ee25c0e8 --- /dev/null +++ b/drivers/net/dsa/b53/b53_mmap.c @@ -0,0 +1,260 @@ +/* + * B53 register access through memory mapped registers + * + * Copyright (C) 2012-2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "b53_priv.h" + +struct b53_mmap_priv { + void __iomem *regs; +}; + +static int b53_mmap_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) +{ + u8 __iomem *regs = dev->priv; + + *val = readb(regs + (page << 8) + reg); + + return 0; +} + +static int b53_mmap_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) +{ + u8 __iomem *regs = dev->priv; + + if (WARN_ON(reg % 2)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && dev->pdata && + dev->pdata->big_endian) + *val = __raw_readw(regs + (page << 8) + reg); + else + *val = readw(regs + (page << 8) + reg); + + return 0; +} + +static int b53_mmap_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) +{ + u8 __iomem *regs = dev->priv; + + if (WARN_ON(reg % 4)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && dev->pdata && + dev->pdata->big_endian) + *val = __raw_readl(regs + (page << 8) + reg); + else + *val = readl(regs + (page << 8) + reg); + + return 0; +} + +static int b53_mmap_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + if (WARN_ON(reg % 2)) + return -EINVAL; + + if (reg % 4) { + u16 lo; + u32 hi; + + b53_mmap_read16(dev, page, reg, &lo); + b53_mmap_read32(dev, page, reg + 2, &hi); + + *val = ((u64)hi << 16) | lo; + } else { + u32 lo; + u16 hi; + + b53_mmap_read32(dev, page, reg, &lo); + b53_mmap_read16(dev, page, reg + 4, &hi); + + *val = ((u64)hi << 32) | lo; + } + + return 0; +} + +static int b53_mmap_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + u32 hi, lo; + + if (WARN_ON(reg % 4)) + return -EINVAL; + + b53_mmap_read32(dev, page, reg, &lo); + b53_mmap_read32(dev, page, reg + 4, &hi); + + *val = ((u64)hi << 32) | lo; + + return 0; +} + +static int b53_mmap_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) +{ + u8 __iomem *regs = dev->priv; + + writeb(value, regs + (page << 8) + reg); + + return 0; +} + +static int b53_mmap_write16(struct b53_device *dev, u8 page, u8 reg, + u16 value) +{ + u8 __iomem *regs = dev->priv; + + if (WARN_ON(reg % 2)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && dev->pdata && + dev->pdata->big_endian) + __raw_writew(value, regs + (page << 8) + reg); + else + writew(value, regs + (page << 8) + reg); + + return 0; +} + +static int b53_mmap_write32(struct b53_device *dev, u8 page, u8 reg, + u32 value) +{ + u8 __iomem *regs = dev->priv; + + if (WARN_ON(reg % 4)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && dev->pdata && + dev->pdata->big_endian) + __raw_writel(value, regs + (page << 8) + reg); + else + writel(value, regs + (page << 8) + reg); + + return 0; +} + +static int b53_mmap_write48(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + if (WARN_ON(reg % 2)) + return -EINVAL; + + if (reg % 4) { + u32 hi = (u32)(value >> 16); + u16 lo = (u16)value; + + b53_mmap_write16(dev, page, reg, lo); + b53_mmap_write32(dev, page, reg + 2, hi); + } else { + u16 hi = (u16)(value >> 32); + u32 lo = (u32)value; + + b53_mmap_write32(dev, page, reg, lo); + b53_mmap_write16(dev, page, reg + 4, hi); + } + + return 0; +} + +static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + u32 hi, lo; + + hi = upper_32_bits(value); + lo = lower_32_bits(value); + + if (WARN_ON(reg % 4)) + return -EINVAL; + + b53_mmap_write32(dev, page, reg, lo); + b53_mmap_write32(dev, page, reg + 4, hi); + + return 0; +} + +static struct b53_io_ops b53_mmap_ops = { + .read8 = b53_mmap_read8, + .read16 = b53_mmap_read16, + .read32 = b53_mmap_read32, + .read48 = b53_mmap_read48, + .read64 = b53_mmap_read64, + .write8 = b53_mmap_write8, + .write16 = b53_mmap_write16, + .write32 = b53_mmap_write32, + .write48 = b53_mmap_write48, + .write64 = b53_mmap_write64, +}; + +static int b53_mmap_probe(struct platform_device *pdev) +{ + struct b53_platform_data *pdata = pdev->dev.platform_data; + struct b53_device *dev; + + if (!pdata) + return -EINVAL; + + dev = b53_switch_alloc(&pdev->dev, &b53_mmap_ops, pdata->regs); + if (!dev) + return -ENOMEM; + + if (pdata) + dev->pdata = pdata; + + platform_set_drvdata(pdev, dev); + + return b53_switch_register(dev); +} + +static int b53_mmap_remove(struct platform_device *pdev) +{ + struct b53_device *dev = platform_get_drvdata(pdev); + + if (dev) + b53_switch_remove(dev); + + return 0; +} + +static const struct of_device_id b53_mmap_of_table[] = { + { .compatible = "brcm,bcm3384-switch" }, + { .compatible = "brcm,bcm6328-switch" }, + { .compatible = "brcm,bcm6368-switch" }, + { .compatible = "brcm,bcm63xx-switch" }, + { /* sentinel */ }, +}; + +static struct platform_driver b53_mmap_driver = { + .probe = b53_mmap_probe, + .remove = b53_mmap_remove, + .driver = { + .name = "b53-switch", + .of_match_table = b53_mmap_of_table, + }, +}; + +module_platform_driver(b53_mmap_driver); +MODULE_AUTHOR("Jonas Gorski "); +MODULE_DESCRIPTION("B53 MMAP access driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h new file mode 100644 index 000000000000..c4844155546b --- /dev/null +++ b/drivers/net/dsa/b53/b53_priv.h @@ -0,0 +1,322 @@ +/* + * B53 common definitions + * + * Copyright (C) 2011-2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __B53_PRIV_H +#define __B53_PRIV_H + +#include +#include +#include +#include + +struct b53_device; + +struct b53_io_ops { + int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); + int (*read16)(struct b53_device *dev, u8 page, u8 reg, u16 *value); + int (*read32)(struct b53_device *dev, u8 page, u8 reg, u32 *value); + int (*read48)(struct b53_device *dev, u8 page, u8 reg, u64 *value); + int (*read64)(struct b53_device *dev, u8 page, u8 reg, u64 *value); + int (*write8)(struct b53_device *dev, u8 page, u8 reg, u8 value); + int (*write16)(struct b53_device *dev, u8 page, u8 reg, u16 value); + int (*write32)(struct b53_device *dev, u8 page, u8 reg, u32 value); + int (*write48)(struct b53_device *dev, u8 page, u8 reg, u64 value); + int (*write64)(struct b53_device *dev, u8 page, u8 reg, u64 value); + int (*phy_read16)(struct b53_device *dev, int addr, int reg, u16 *value); + int (*phy_write16)(struct b53_device *dev, int addr, int reg, u16 value); +}; + +enum { + BCM5325_DEVICE_ID = 0x25, + BCM5365_DEVICE_ID = 0x65, + BCM5395_DEVICE_ID = 0x95, + BCM5397_DEVICE_ID = 0x97, + BCM5398_DEVICE_ID = 0x98, + BCM53115_DEVICE_ID = 0x53115, + BCM53125_DEVICE_ID = 0x53125, + BCM53128_DEVICE_ID = 0x53128, + BCM63XX_DEVICE_ID = 0x6300, + BCM53010_DEVICE_ID = 0x53010, + BCM53011_DEVICE_ID = 0x53011, + BCM53012_DEVICE_ID = 0x53012, + BCM53018_DEVICE_ID = 0x53018, + BCM53019_DEVICE_ID = 0x53019, +}; + +#define B53_N_PORTS 9 +#define B53_N_PORTS_25 6 + +struct b53_port { +}; + +struct b53_device { + struct dsa_switch *ds; + struct b53_platform_data *pdata; + const char *name; + + struct mutex reg_mutex; + struct mutex stats_mutex; + const struct b53_io_ops *ops; + + /* chip specific data */ + u32 chip_id; + u8 core_rev; + u8 vta_regs[3]; + u8 duplex_reg; + u8 jumbo_pm_reg; + u8 jumbo_size_reg; + int reset_gpio; + + /* used ports mask */ + u16 enabled_ports; + unsigned int cpu_port; + + /* connect specific data */ + u8 current_page; + struct device *dev; + + /* Master MDIO bus we got probed from */ + struct mii_bus *bus; + + /* Slave MDIO bus we created */ + struct mii_bus *slave_bus; + void *priv; + + /* run time configuration */ + unsigned enable_jumbo:1; + unsigned allow_vid_4095:1; + unsigned int num_vlans; + unsigned int num_ports; + struct b53_port *ports; +}; + +#define b53_for_each_port(dev, i) \ + for (i = 0; i < B53_N_PORTS; i++) \ + if (dev->enabled_ports & BIT(i)) + + +static inline int is5325(struct b53_device *dev) +{ + return dev->chip_id == BCM5325_DEVICE_ID; +} + +static inline int is5365(struct b53_device *dev) +{ +#ifdef CONFIG_BCM47XX + return dev->chip_id == BCM5365_DEVICE_ID; +#else + return 0; +#endif +} + +static inline int is5397_98(struct b53_device *dev) +{ + return dev->chip_id == BCM5397_DEVICE_ID || + dev->chip_id == BCM5398_DEVICE_ID; +} + +static inline int is539x(struct b53_device *dev) +{ + return dev->chip_id == BCM5395_DEVICE_ID || + dev->chip_id == BCM5397_DEVICE_ID || + dev->chip_id == BCM5398_DEVICE_ID; +} + +static inline int is531x5(struct b53_device *dev) +{ + return dev->chip_id == BCM53115_DEVICE_ID || + dev->chip_id == BCM53125_DEVICE_ID || + dev->chip_id == BCM53128_DEVICE_ID; +} + +static inline int is63xx(struct b53_device *dev) +{ +#ifdef CONFIG_BCM63XX + return dev->chip_id == BCM63XX_DEVICE_ID; +#else + return 0; +#endif +} + +static inline int is5301x(struct b53_device *dev) +{ + return dev->chip_id == BCM53010_DEVICE_ID || + dev->chip_id == BCM53011_DEVICE_ID || + dev->chip_id == BCM53012_DEVICE_ID || + dev->chip_id == BCM53018_DEVICE_ID || + dev->chip_id == BCM53019_DEVICE_ID; +} + +#define B53_CPU_PORT_25 5 +#define B53_CPU_PORT 8 + +static inline int is_cpu_port(struct b53_device *dev, int port) +{ + return dev->cpu_port; +} + +struct b53_device *b53_switch_alloc(struct device *base, struct b53_io_ops *ops, + void *priv); + +int b53_switch_detect(struct b53_device *dev); + +int b53_switch_register(struct b53_device *dev); + +static inline void b53_switch_remove(struct b53_device *dev) +{ + dsa_unregister_switch(dev->ds); +} + +static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->read8(dev, page, reg, val); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->read16(dev, page, reg, val); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->read32(dev, page, reg, val); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->read48(dev, page, reg, val); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->read64(dev, page, reg, val); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->write8(dev, page, reg, value); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_write16(struct b53_device *dev, u8 page, u8 reg, + u16 value) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->write16(dev, page, reg, value); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_write32(struct b53_device *dev, u8 page, u8 reg, + u32 value) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->write32(dev, page, reg, value); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_write48(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->write48(dev, page, reg, value); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + int ret; + + mutex_lock(&dev->reg_mutex); + ret = dev->ops->write64(dev, page, reg, value); + mutex_unlock(&dev->reg_mutex); + + return ret; +} + +#ifdef CONFIG_BCM47XX + +#include +#include +#include +static inline int b53_switch_get_reset_gpio(struct b53_device *dev) +{ + enum bcm47xx_board board = bcm47xx_board_get(); + + switch (board) { + case BCM47XX_BOARD_LINKSYS_WRT300NV11: + case BCM47XX_BOARD_LINKSYS_WRT310NV1: + return 8; + default: + return bcm47xx_nvram_gpio_pin("robo_reset"); + } +} +#else +static inline int b53_switch_get_reset_gpio(struct b53_device *dev) +{ + return -ENOENT; +} +#endif +#endif diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h new file mode 100644 index 000000000000..ccf8af7717d3 --- /dev/null +++ b/drivers/net/dsa/b53/b53_regs.h @@ -0,0 +1,358 @@ +/* + * B53 register definitions + * + * Copyright (C) 2004 Broadcom Corporation + * Copyright (C) 2011-2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __B53_REGS_H +#define __B53_REGS_H + +/* Management Port (SMP) Page offsets */ +#define B53_CTRL_PAGE 0x00 /* Control */ +#define B53_STAT_PAGE 0x01 /* Status */ +#define B53_MGMT_PAGE 0x02 /* Management Mode */ +#define B53_MIB_AC_PAGE 0x03 /* MIB Autocast */ +#define B53_ARLCTRL_PAGE 0x04 /* ARL Control */ +#define B53_ARLIO_PAGE 0x05 /* ARL Access */ +#define B53_FRAMEBUF_PAGE 0x06 /* Management frame access */ +#define B53_MEM_ACCESS_PAGE 0x08 /* Memory access */ + +/* PHY Registers */ +#define B53_PORT_MII_PAGE(i) (0x10 + (i)) /* Port i MII Registers */ +#define B53_IM_PORT_PAGE 0x18 /* Inverse MII Port (to EMAC) */ +#define B53_ALL_PORT_PAGE 0x19 /* All ports MII (broadcast) */ + +/* MIB registers */ +#define B53_MIB_PAGE(i) (0x20 + (i)) + +/* Quality of Service (QoS) Registers */ +#define B53_QOS_PAGE 0x30 + +/* Port VLAN Page */ +#define B53_PVLAN_PAGE 0x31 + +/* VLAN Registers */ +#define B53_VLAN_PAGE 0x34 + +/* Jumbo Frame Registers */ +#define B53_JUMBO_PAGE 0x40 + +/* CFP Configuration Registers Page */ +#define B53_CFP_PAGE 0xa1 + +/************************************************************************* + * Control Page registers + *************************************************************************/ + +/* Port Control Register (8 bit) */ +#define B53_PORT_CTRL(i) (0x00 + (i)) +#define PORT_CTRL_RX_DISABLE BIT(0) +#define PORT_CTRL_TX_DISABLE BIT(1) +#define PORT_CTRL_RX_BCST_EN BIT(2) /* Broadcast RX (P8 only) */ +#define PORT_CTRL_RX_MCST_EN BIT(3) /* Multicast RX (P8 only) */ +#define PORT_CTRL_RX_UCST_EN BIT(4) /* Unicast RX (P8 only) */ +#define PORT_CTRL_STP_STATE_S 5 +#define PORT_CTRL_STP_STATE_MASK (0x7 << PORT_CTRL_STP_STATE_S) + +/* SMP Control Register (8 bit) */ +#define B53_SMP_CTRL 0x0a + +/* Switch Mode Control Register (8 bit) */ +#define B53_SWITCH_MODE 0x0b +#define SM_SW_FWD_MODE BIT(0) /* 1 = Managed Mode */ +#define SM_SW_FWD_EN BIT(1) /* Forwarding Enable */ + +/* IMP Port state override register (8 bit) */ +#define B53_PORT_OVERRIDE_CTRL 0x0e +#define PORT_OVERRIDE_LINK BIT(0) +#define PORT_OVERRIDE_FULL_DUPLEX BIT(1) /* 0 = Half Duplex */ +#define PORT_OVERRIDE_SPEED_S 2 +#define PORT_OVERRIDE_SPEED_10M (0 << PORT_OVERRIDE_SPEED_S) +#define PORT_OVERRIDE_SPEED_100M (1 << PORT_OVERRIDE_SPEED_S) +#define PORT_OVERRIDE_SPEED_1000M (2 << PORT_OVERRIDE_SPEED_S) +#define PORT_OVERRIDE_RV_MII_25 BIT(4) /* BCM5325 only */ +#define PORT_OVERRIDE_RX_FLOW BIT(4) +#define PORT_OVERRIDE_TX_FLOW BIT(5) +#define PORT_OVERRIDE_SPEED_2000M BIT(6) /* BCM5301X only, requires setting 1000M */ +#define PORT_OVERRIDE_EN BIT(7) /* Use the register contents */ + +/* Power-down mode control */ +#define B53_PD_MODE_CTRL_25 0x0f + +/* IP Multicast control (8 bit) */ +#define B53_IP_MULTICAST_CTRL 0x21 +#define B53_IPMC_FWD_EN BIT(1) +#define B53_UC_FWD_EN BIT(6) +#define B53_MC_FWD_EN BIT(7) + +/* (16 bit) */ +#define B53_UC_FLOOD_MASK 0x32 +#define B53_MC_FLOOD_MASK 0x34 +#define B53_IPMC_FLOOD_MASK 0x36 + +/* + * Override Ports 0-7 State on devices with xMII interfaces (8 bit) + * + * For port 8 still use B53_PORT_OVERRIDE_CTRL + * Please note that not all ports are available on every hardware, e.g. BCM5301X + * don't include overriding port 6, BCM63xx also have some limitations. + */ +#define B53_GMII_PORT_OVERRIDE_CTRL(i) (0x58 + (i)) +#define GMII_PO_LINK BIT(0) +#define GMII_PO_FULL_DUPLEX BIT(1) /* 0 = Half Duplex */ +#define GMII_PO_SPEED_S 2 +#define GMII_PO_SPEED_10M (0 << GMII_PO_SPEED_S) +#define GMII_PO_SPEED_100M (1 << GMII_PO_SPEED_S) +#define GMII_PO_SPEED_1000M (2 << GMII_PO_SPEED_S) +#define GMII_PO_RX_FLOW BIT(4) +#define GMII_PO_TX_FLOW BIT(5) +#define GMII_PO_EN BIT(6) /* Use the register contents */ +#define GMII_PO_SPEED_2000M BIT(7) /* BCM5301X only, requires setting 1000M */ + +#define B53_RGMII_CTRL_IMP 0x60 +#define RGMII_CTRL_ENABLE_GMII BIT(7) +#define RGMII_CTRL_TIMING_SEL BIT(2) +#define RGMII_CTRL_DLL_RXC BIT(1) +#define RGMII_CTRL_DLL_TXC BIT(0) + +#define B53_RGMII_CTRL_P(i) (B53_RGMII_CTRL_IMP + (i)) + +/* Software reset register (8 bit) */ +#define B53_SOFTRESET 0x79 +#define SW_RST BIT(7) +#define EN_SW_RST BIT(4) + +/* Fast Aging Control register (8 bit) */ +#define B53_FAST_AGE_CTRL 0x88 +#define FAST_AGE_STATIC BIT(0) +#define FAST_AGE_DYNAMIC BIT(1) +#define FAST_AGE_PORT BIT(2) +#define FAST_AGE_VLAN BIT(3) +#define FAST_AGE_STP BIT(4) +#define FAST_AGE_MC BIT(5) +#define FAST_AGE_DONE BIT(7) + +/************************************************************************* + * Status Page registers + *************************************************************************/ + +/* Link Status Summary Register (16bit) */ +#define B53_LINK_STAT 0x00 + +/* Link Status Change Register (16 bit) */ +#define B53_LINK_STAT_CHANGE 0x02 + +/* Port Speed Summary Register (16 bit for FE, 32 bit for GE) */ +#define B53_SPEED_STAT 0x04 +#define SPEED_PORT_FE(reg, port) (((reg) >> (port)) & 1) +#define SPEED_PORT_GE(reg, port) (((reg) >> 2 * (port)) & 3) +#define SPEED_STAT_10M 0 +#define SPEED_STAT_100M 1 +#define SPEED_STAT_1000M 2 + +/* Duplex Status Summary (16 bit) */ +#define B53_DUPLEX_STAT_FE 0x06 +#define B53_DUPLEX_STAT_GE 0x08 +#define B53_DUPLEX_STAT_63XX 0x0c + +/* Revision ID register for BCM5325 */ +#define B53_REV_ID_25 0x50 + +/* Strap Value (48 bit) */ +#define B53_STRAP_VALUE 0x70 +#define SV_GMII_CTRL_115 BIT(27) + +/************************************************************************* + * Management Mode Page Registers + *************************************************************************/ + +/* Global Management Config Register (8 bit) */ +#define B53_GLOBAL_CONFIG 0x00 +#define GC_RESET_MIB 0x01 +#define GC_RX_BPDU_EN 0x02 +#define GC_MIB_AC_HDR_EN 0x10 +#define GC_MIB_AC_EN 0x20 +#define GC_FRM_MGMT_PORT_M 0xC0 +#define GC_FRM_MGMT_PORT_04 0x00 +#define GC_FRM_MGMT_PORT_MII 0x80 + +/* Broadcom Header control register (8 bit) */ +#define B53_BRCM_HDR 0x03 +#define BRCM_HDR_P8_EN BIT(0) /* Enable tagging on port 8 */ +#define BRCM_HDR_P5_EN BIT(1) /* Enable tagging on port 5 */ + +/* Device ID register (8 or 32 bit) */ +#define B53_DEVICE_ID 0x30 + +/* Revision ID register (8 bit) */ +#define B53_REV_ID 0x40 + +/************************************************************************* + * ARL Access Page Registers + *************************************************************************/ + +/* VLAN Table Access Register (8 bit) */ +#define B53_VT_ACCESS 0x80 +#define B53_VT_ACCESS_9798 0x60 /* for BCM5397/BCM5398 */ +#define B53_VT_ACCESS_63XX 0x60 /* for BCM6328/62/68 */ +#define VTA_CMD_WRITE 0 +#define VTA_CMD_READ 1 +#define VTA_CMD_CLEAR 2 +#define VTA_START_CMD BIT(7) + +/* VLAN Table Index Register (16 bit) */ +#define B53_VT_INDEX 0x81 +#define B53_VT_INDEX_9798 0x61 +#define B53_VT_INDEX_63XX 0x62 + +/* VLAN Table Entry Register (32 bit) */ +#define B53_VT_ENTRY 0x83 +#define B53_VT_ENTRY_9798 0x63 +#define B53_VT_ENTRY_63XX 0x64 +#define VTE_MEMBERS 0x1ff +#define VTE_UNTAG_S 9 +#define VTE_UNTAG (0x1ff << 9) + +/************************************************************************* + * Port VLAN Registers + *************************************************************************/ + +/* Port VLAN mask (16 bit) IMP port is always 8, also on 5325 & co */ +#define B53_PVLAN_PORT_MASK(i) ((i) * 2) + +/************************************************************************* + * 802.1Q Page Registers + *************************************************************************/ + +/* Global QoS Control (8 bit) */ +#define B53_QOS_GLOBAL_CTL 0x00 + +/* Enable 802.1Q for individual Ports (16 bit) */ +#define B53_802_1P_EN 0x04 + +/************************************************************************* + * VLAN Page Registers + *************************************************************************/ + +/* VLAN Control 0 (8 bit) */ +#define B53_VLAN_CTRL0 0x00 +#define VC0_8021PF_CTRL_MASK 0x3 +#define VC0_8021PF_CTRL_NONE 0x0 +#define VC0_8021PF_CTRL_CHANGE_PRI 0x1 +#define VC0_8021PF_CTRL_CHANGE_VID 0x2 +#define VC0_8021PF_CTRL_CHANGE_BOTH 0x3 +#define VC0_8021QF_CTRL_MASK 0xc +#define VC0_8021QF_CTRL_CHANGE_PRI 0x1 +#define VC0_8021QF_CTRL_CHANGE_VID 0x2 +#define VC0_8021QF_CTRL_CHANGE_BOTH 0x3 +#define VC0_RESERVED_1 BIT(1) +#define VC0_DROP_VID_MISS BIT(4) +#define VC0_VID_HASH_VID BIT(5) +#define VC0_VID_CHK_EN BIT(6) /* Use VID,DA or VID,SA */ +#define VC0_VLAN_EN BIT(7) /* 802.1Q VLAN Enabled */ + +/* VLAN Control 1 (8 bit) */ +#define B53_VLAN_CTRL1 0x01 +#define VC1_RX_MCST_TAG_EN BIT(1) +#define VC1_RX_MCST_FWD_EN BIT(2) +#define VC1_RX_MCST_UNTAG_EN BIT(3) + +/* VLAN Control 2 (8 bit) */ +#define B53_VLAN_CTRL2 0x02 + +/* VLAN Control 3 (8 bit when BCM5325, 16 bit else) */ +#define B53_VLAN_CTRL3 0x03 +#define B53_VLAN_CTRL3_63XX 0x04 +#define VC3_MAXSIZE_1532 BIT(6) /* 5325 only */ +#define VC3_HIGH_8BIT_EN BIT(7) /* 5325 only */ + +/* VLAN Control 4 (8 bit) */ +#define B53_VLAN_CTRL4 0x05 +#define B53_VLAN_CTRL4_25 0x04 +#define B53_VLAN_CTRL4_63XX 0x06 +#define VC4_ING_VID_CHECK_S 6 +#define VC4_ING_VID_CHECK_MASK (0x3 << VC4_ING_VID_CHECK_S) +#define VC4_ING_VID_VIO_FWD 0 /* forward, but do not learn */ +#define VC4_ING_VID_VIO_DROP 1 /* drop VID violations */ +#define VC4_NO_ING_VID_CHK 2 /* do not check */ +#define VC4_ING_VID_VIO_TO_IMP 3 /* redirect to MII port */ + +/* VLAN Control 5 (8 bit) */ +#define B53_VLAN_CTRL5 0x06 +#define B53_VLAN_CTRL5_25 0x05 +#define B53_VLAN_CTRL5_63XX 0x07 +#define VC5_VID_FFF_EN BIT(2) +#define VC5_DROP_VTABLE_MISS BIT(3) + +/* VLAN Control 6 (8 bit) */ +#define B53_VLAN_CTRL6 0x07 +#define B53_VLAN_CTRL6_63XX 0x08 + +/* VLAN Table Access Register (16 bit) */ +#define B53_VLAN_TABLE_ACCESS_25 0x06 /* BCM5325E/5350 */ +#define B53_VLAN_TABLE_ACCESS_65 0x08 /* BCM5365 */ +#define VTA_VID_LOW_MASK_25 0xf +#define VTA_VID_LOW_MASK_65 0xff +#define VTA_VID_HIGH_S_25 4 +#define VTA_VID_HIGH_S_65 8 +#define VTA_VID_HIGH_MASK_25 (0xff << VTA_VID_HIGH_S_25E) +#define VTA_VID_HIGH_MASK_65 (0xf << VTA_VID_HIGH_S_65) +#define VTA_RW_STATE BIT(12) +#define VTA_RW_STATE_RD 0 +#define VTA_RW_STATE_WR BIT(12) +#define VTA_RW_OP_EN BIT(13) + +/* VLAN Read/Write Registers for (16/32 bit) */ +#define B53_VLAN_WRITE_25 0x08 +#define B53_VLAN_WRITE_65 0x0a +#define B53_VLAN_READ 0x0c +#define VA_MEMBER_MASK 0x3f +#define VA_UNTAG_S_25 6 +#define VA_UNTAG_MASK_25 0x3f +#define VA_UNTAG_S_65 7 +#define VA_UNTAG_MASK_65 0x1f +#define VA_VID_HIGH_S 12 +#define VA_VID_HIGH_MASK (0xffff << VA_VID_HIGH_S) +#define VA_VALID_25 BIT(20) +#define VA_VALID_25_R4 BIT(24) +#define VA_VALID_65 BIT(14) + +/* VLAN Port Default Tag (16 bit) */ +#define B53_VLAN_PORT_DEF_TAG(i) (0x10 + 2 * (i)) + +/************************************************************************* + * Jumbo Frame Page Registers + *************************************************************************/ + +/* Jumbo Enable Port Mask (bit i == port i enabled) (32 bit) */ +#define B53_JUMBO_PORT_MASK 0x01 +#define B53_JUMBO_PORT_MASK_63XX 0x04 +#define JPM_10_100_JUMBO_EN BIT(24) /* GigE always enabled */ + +/* Good Frame Max Size without 802.1Q TAG (16 bit) */ +#define B53_JUMBO_MAX_SIZE 0x05 +#define B53_JUMBO_MAX_SIZE_63XX 0x08 +#define JMS_MIN_SIZE 1518 +#define JMS_MAX_SIZE 9724 + +/************************************************************************* + * CFP Configuration Page Registers + *************************************************************************/ + +/* CFP Control Register with ports map (8 bit) */ +#define B53_CFP_CTRL 0x00 + +#endif /* !__B53_REGS_H */ diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c new file mode 100644 index 000000000000..2bda0b5f1578 --- /dev/null +++ b/drivers/net/dsa/b53/b53_spi.c @@ -0,0 +1,331 @@ +/* + * B53 register access through SPI + * + * Copyright (C) 2011-2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "b53_priv.h" + +#define B53_SPI_DATA 0xf0 + +#define B53_SPI_STATUS 0xfe +#define B53_SPI_CMD_SPIF BIT(7) +#define B53_SPI_CMD_RACK BIT(5) + +#define B53_SPI_CMD_READ 0x00 +#define B53_SPI_CMD_WRITE 0x01 +#define B53_SPI_CMD_NORMAL 0x60 +#define B53_SPI_CMD_FAST 0x10 + +#define B53_SPI_PAGE_SELECT 0xff + +static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, + unsigned int len) +{ + u8 txbuf[2]; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; + txbuf[1] = reg; + + return spi_write_then_read(spi, txbuf, 2, val, len); +} + +static inline int b53_spi_clear_status(struct spi_device *spi) +{ + unsigned int i; + u8 rxbuf; + int ret; + + for (i = 0; i < 10; i++) { + ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); + if (ret) + return ret; + + if (!(rxbuf & B53_SPI_CMD_SPIF)) + break; + + mdelay(1); + } + + if (i == 10) + return -EIO; + + return 0; +} + +static inline int b53_spi_set_page(struct spi_device *spi, u8 page) +{ + u8 txbuf[3]; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = B53_SPI_PAGE_SELECT; + txbuf[2] = page; + + return spi_write(spi, txbuf, sizeof(txbuf)); +} + +static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) +{ + int ret = b53_spi_clear_status(spi); + + if (ret) + return ret; + + return b53_spi_set_page(spi, page); +} + +static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) +{ + u8 rxbuf; + int retry_count; + int ret; + + ret = b53_spi_read_reg(spi, reg, &rxbuf, 1); + if (ret) + return ret; + + for (retry_count = 0; retry_count < 10; retry_count++) { + ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); + if (ret) + return ret; + + if (rxbuf & B53_SPI_CMD_RACK) + break; + + mdelay(1); + } + + if (retry_count == 10) + return -EIO; + + return 0; +} + +static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, + unsigned int len) +{ + struct spi_device *spi = dev->priv; + int ret; + + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + ret = b53_spi_prepare_reg_read(spi, reg); + if (ret) + return ret; + + return b53_spi_read_reg(spi, B53_SPI_DATA, data, len); +} + +static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) +{ + return b53_spi_read(dev, page, reg, val, 1); +} + +static int b53_spi_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) +{ + int ret = b53_spi_read(dev, page, reg, (u8 *)val, 2); + + if (!ret) + *val = le16_to_cpu(*val); + + return ret; +} + +static int b53_spi_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) +{ + int ret = b53_spi_read(dev, page, reg, (u8 *)val, 4); + + if (!ret) + *val = le32_to_cpu(*val); + + return ret; +} + +static int b53_spi_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + int ret; + + *val = 0; + ret = b53_spi_read(dev, page, reg, (u8 *)val, 6); + if (!ret) + *val = le64_to_cpu(*val); + + return ret; +} + +static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + int ret = b53_spi_read(dev, page, reg, (u8 *)val, 8); + + if (!ret) + *val = le64_to_cpu(*val); + + return ret; +} + +static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) +{ + struct spi_device *spi = dev->priv; + int ret; + u8 txbuf[3]; + + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + txbuf[2] = value; + + return spi_write(spi, txbuf, sizeof(txbuf)); +} + +static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) +{ + struct spi_device *spi = dev->priv; + int ret; + u8 txbuf[4]; + + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le16(value, &txbuf[2]); + + return spi_write(spi, txbuf, sizeof(txbuf)); +} + +static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) +{ + struct spi_device *spi = dev->priv; + int ret; + u8 txbuf[6]; + + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le32(value, &txbuf[2]); + + return spi_write(spi, txbuf, sizeof(txbuf)); +} + +static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) +{ + struct spi_device *spi = dev->priv; + int ret; + u8 txbuf[10]; + + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le64(value, &txbuf[2]); + + return spi_write(spi, txbuf, sizeof(txbuf) - 2); +} + +static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) +{ + struct spi_device *spi = dev->priv; + int ret; + u8 txbuf[10]; + + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le64(value, &txbuf[2]); + + return spi_write(spi, txbuf, sizeof(txbuf)); +} + +static struct b53_io_ops b53_spi_ops = { + .read8 = b53_spi_read8, + .read16 = b53_spi_read16, + .read32 = b53_spi_read32, + .read48 = b53_spi_read48, + .read64 = b53_spi_read64, + .write8 = b53_spi_write8, + .write16 = b53_spi_write16, + .write32 = b53_spi_write32, + .write48 = b53_spi_write48, + .write64 = b53_spi_write64, +}; + +static int b53_spi_probe(struct spi_device *spi) +{ + struct b53_device *dev; + int ret; + + dev = b53_switch_alloc(&spi->dev, &b53_spi_ops, spi); + if (!dev) + return -ENOMEM; + + if (spi->dev.platform_data) + dev->pdata = spi->dev.platform_data; + + ret = b53_switch_register(dev); + if (ret) + return ret; + + spi_set_drvdata(spi, dev); + + return 0; +} + +static int b53_spi_remove(struct spi_device *spi) +{ + struct b53_device *dev = spi_get_drvdata(spi); + + if (dev) + b53_switch_remove(dev); + + return 0; +} + +static struct spi_driver b53_spi_driver = { + .driver = { + .name = "b53-switch", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = b53_spi_probe, + .remove = b53_spi_remove, +}; + +module_spi_driver(b53_spi_driver); + +MODULE_AUTHOR("Jonas Gorski "); +MODULE_DESCRIPTION("B53 SPI access driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/dsa/b53/b53_srab.c b/drivers/net/dsa/b53/b53_srab.c new file mode 100644 index 000000000000..70fd47284535 --- /dev/null +++ b/drivers/net/dsa/b53/b53_srab.c @@ -0,0 +1,415 @@ +/* + * B53 register access through Switch Register Access Bridge Registers + * + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "b53_priv.h" + +/* command and status register of the SRAB */ +#define B53_SRAB_CMDSTAT 0x2c +#define B53_SRAB_CMDSTAT_RST BIT(2) +#define B53_SRAB_CMDSTAT_WRITE BIT(1) +#define B53_SRAB_CMDSTAT_GORDYN BIT(0) +#define B53_SRAB_CMDSTAT_PAGE 24 +#define B53_SRAB_CMDSTAT_REG 16 + +/* high order word of write data to switch registe */ +#define B53_SRAB_WD_H 0x30 + +/* low order word of write data to switch registe */ +#define B53_SRAB_WD_L 0x34 + +/* high order word of read data from switch register */ +#define B53_SRAB_RD_H 0x38 + +/* low order word of read data from switch register */ +#define B53_SRAB_RD_L 0x3c + +/* command and status register of the SRAB */ +#define B53_SRAB_CTRLS 0x40 +#define B53_SRAB_CTRLS_RCAREQ BIT(3) +#define B53_SRAB_CTRLS_RCAGNT BIT(4) +#define B53_SRAB_CTRLS_SW_INIT_DONE BIT(6) + +/* the register captures interrupt pulses from the switch */ +#define B53_SRAB_INTR 0x44 +#define B53_SRAB_INTR_P(x) BIT(x) +#define B53_SRAB_SWITCH_PHY BIT(8) +#define B53_SRAB_1588_SYNC BIT(9) +#define B53_SRAB_IMP1_SLEEP_TIMER BIT(10) +#define B53_SRAB_P7_SLEEP_TIMER BIT(11) +#define B53_SRAB_IMP0_SLEEP_TIMER BIT(12) + +struct b53_srab_priv { + void __iomem *regs; +}; + +static int b53_srab_request_grant(struct b53_device *dev) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + u32 ctrls; + int i; + + ctrls = readl(regs + B53_SRAB_CTRLS); + ctrls |= B53_SRAB_CTRLS_RCAREQ; + writel(ctrls, regs + B53_SRAB_CTRLS); + + for (i = 0; i < 20; i++) { + ctrls = readl(regs + B53_SRAB_CTRLS); + if (ctrls & B53_SRAB_CTRLS_RCAGNT) + break; + usleep_range(10, 100); + } + if (WARN_ON(i == 5)) + return -EIO; + + return 0; +} + +static void b53_srab_release_grant(struct b53_device *dev) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + u32 ctrls; + + ctrls = readl(regs + B53_SRAB_CTRLS); + ctrls &= ~B53_SRAB_CTRLS_RCAREQ; + writel(ctrls, regs + B53_SRAB_CTRLS); +} + +static int b53_srab_op(struct b53_device *dev, u8 page, u8 reg, u32 op) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int i; + u32 cmdstat; + + /* set register address */ + cmdstat = (page << B53_SRAB_CMDSTAT_PAGE) | + (reg << B53_SRAB_CMDSTAT_REG) | + B53_SRAB_CMDSTAT_GORDYN | + op; + writel(cmdstat, regs + B53_SRAB_CMDSTAT); + + /* check if operation completed */ + for (i = 0; i < 5; ++i) { + cmdstat = readl(regs + B53_SRAB_CMDSTAT); + if (!(cmdstat & B53_SRAB_CMDSTAT_GORDYN)) + break; + usleep_range(10, 100); + } + + if (WARN_ON(i == 5)) + return -EIO; + + return 0; +} + +static int b53_srab_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + ret = b53_srab_op(dev, page, reg, 0); + if (ret) + goto err; + + *val = readl(regs + B53_SRAB_RD_L) & 0xff; + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + ret = b53_srab_op(dev, page, reg, 0); + if (ret) + goto err; + + *val = readl(regs + B53_SRAB_RD_L) & 0xffff; + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + ret = b53_srab_op(dev, page, reg, 0); + if (ret) + goto err; + + *val = readl(regs + B53_SRAB_RD_L); + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + ret = b53_srab_op(dev, page, reg, 0); + if (ret) + goto err; + + *val = readl(regs + B53_SRAB_RD_L); + *val += ((u64)readl(regs + B53_SRAB_RD_H) & 0xffff) << 32; + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + ret = b53_srab_op(dev, page, reg, 0); + if (ret) + goto err; + + *val = readl(regs + B53_SRAB_RD_L); + *val += (u64)readl(regs + B53_SRAB_RD_H) << 32; + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + writel(value, regs + B53_SRAB_WD_L); + + ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_write16(struct b53_device *dev, u8 page, u8 reg, + u16 value) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + writel(value, regs + B53_SRAB_WD_L); + + ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_write32(struct b53_device *dev, u8 page, u8 reg, + u32 value) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + writel(value, regs + B53_SRAB_WD_L); + + ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_write48(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + writel((u32)value, regs + B53_SRAB_WD_L); + writel((u16)(value >> 32), regs + B53_SRAB_WD_H); + + ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static int b53_srab_write64(struct b53_device *dev, u8 page, u8 reg, + u64 value) +{ + struct b53_srab_priv *priv = dev->priv; + u8 __iomem *regs = priv->regs; + int ret = 0; + + ret = b53_srab_request_grant(dev); + if (ret) + goto err; + + writel((u32)value, regs + B53_SRAB_WD_L); + writel((u32)(value >> 32), regs + B53_SRAB_WD_H); + + ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); + +err: + b53_srab_release_grant(dev); + + return ret; +} + +static struct b53_io_ops b53_srab_ops = { + .read8 = b53_srab_read8, + .read16 = b53_srab_read16, + .read32 = b53_srab_read32, + .read48 = b53_srab_read48, + .read64 = b53_srab_read64, + .write8 = b53_srab_write8, + .write16 = b53_srab_write16, + .write32 = b53_srab_write32, + .write48 = b53_srab_write48, + .write64 = b53_srab_write64, +}; + +static int b53_srab_probe(struct platform_device *pdev) +{ + struct b53_srab_priv *priv; + struct b53_device *dev; + struct resource *r; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(priv->regs)) + return -ENOMEM; + + dev = b53_switch_alloc(&pdev->dev, &b53_srab_ops, priv); + if (!dev) + return -ENOMEM; + + platform_set_drvdata(pdev, dev); + + return b53_switch_register(dev); +} + +static int b53_srab_remove(struct platform_device *pdev) +{ + struct b53_device *dev = platform_get_drvdata(pdev); + + if (dev) + b53_switch_remove(dev); + + return 0; +} + +static const struct of_device_id b53_srab_of_match[] = { + { .compatible = "brcm,bcm53010-srab" }, + { .compatible = "brcm,bcm53011-srab" }, + { .compatible = "brcm,bcm53012-srab" }, + { .compatible = "brcm,bcm53018-srab" }, + { .compatible = "brcm,bcm53019-srab" }, + { .compatible = "brcm,bcm5301x-srab" }, + { /* sentinel */ }, +}; + +static struct platform_driver b53_srab_driver = { + .probe = b53_srab_probe, + .remove = b53_srab_remove, + .driver = { + .name = "b53-srab-switch", + .of_match_table = b53_srab_of_match, + }, +}; + +module_platform_driver(b53_srab_driver); +MODULE_AUTHOR("Hauke Mehrtens "); +MODULE_DESCRIPTION("B53 Switch Register Access Bridge Registers (SRAB) access driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/include/linux/platform_data/b53.h b/include/linux/platform_data/b53.h new file mode 100644 index 000000000000..69d279c0da96 --- /dev/null +++ b/include/linux/platform_data/b53.h @@ -0,0 +1,33 @@ +/* + * B53 platform data + * + * Copyright (C) 2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __B53_H +#define __B53_H + +#include + +struct b53_platform_data { + u32 chip_id; + u16 enabled_ports; + + /* only used by MMAP'd driver */ + unsigned big_endian:1; + void __iomem *regs; +}; + +#endif -- cgit v1.3-14-g43fede From 06173fe33a3fd239540bd188f1f12a39e99b6c83 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jun 2016 13:38:28 +0300 Subject: Documentation/sphinx: remove unnecessary temporary variable Leftover cruft. No functional changes. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 4adfb0e91ecc..2856376cc62c 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -59,7 +59,6 @@ class KernelDocDirective(Directive): env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) - source = filename # FIXME: make this nicer and more robust against errors if 'export' in self.options: @@ -105,7 +104,7 @@ class KernelDocDirective(Directive): lineoffset = int(match.group(1)) - 1 # we must eat our comments since the upset the markup else: - result.append(line, source, lineoffset) + result.append(line, filename, lineoffset) lineoffset += 1 node = nodes.section() -- cgit v1.3-14-g43fede From 057de5c4dd536bdf29275ec75910737087594860 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jun 2016 10:25:40 +0300 Subject: Documentation/sphinx: use a more sensible string split in kernel-doc extension Using the default str.split doesn't return empty strings like the current version does. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 2856376cc62c..d6a76f9a0ba5 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -68,7 +68,7 @@ class KernelDocDirective(Directive): elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'functions' in self.options: - for f in str(self.options.get('functions')).split(' '): + for f in str(self.options.get('functions')).split(): cmd += ['-function', f] cmd += [filename] -- cgit v1.3-14-g43fede From 15c9705f0c8af2d19dede9866aec364746b269ef Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 19 Mar 2015 17:36:43 +0100 Subject: KVM: s390: interface to query and configure cpu features For now, we only have an interface to query and configure facilities indicated via STFL(E). However, we also have features indicated via SCLP, that have to be indicated to the guest by user space and usually require KVM support. This patch allows user space to query and configure available cpu features for the guest. Please note that disabling a feature doesn't necessarily mean that it is completely disabled (e.g. ESOP is mostly handled by the SIE). We will try our best to disable it. Most features (e.g. SCLP) can't directly be forwarded, as most of them need in addition to hardware support, support in KVM. As we later on want to turn these features in KVM explicitly on/off (to simulate different behavior), we have to filter all features provided by the hardware and make them configurable. Signed-off-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- Documentation/virtual/kvm/devices/vm.txt | 27 ++++++++++++++ arch/s390/include/asm/kvm_host.h | 2 + arch/s390/include/uapi/asm/kvm.h | 8 ++++ arch/s390/kvm/kvm-s390.c | 63 ++++++++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 6 +++ 5 files changed, 106 insertions(+) (limited to 'Documentation') diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index a9ea8774a45f..0ed6808b9965 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt @@ -85,6 +85,33 @@ Returns: -EBUSY in case 1 or more vcpus are already activated (only in write -ENOMEM if not enough memory is available to process the ioctl 0 in case of success +2.3. ATTRIBUTE: KVM_S390_VM_CPU_MACHINE_FEAT (r/o) + +Allows user space to retrieve available cpu features. A feature is available if +provided by the hardware and supported by kvm. In theory, cpu features could +even be completely emulated by kvm. + +struct kvm_s390_vm_cpu_feat { + __u64 feat[16]; # Bitmap (1 = feature available), MSB 0 bit numbering +}; + +Parameters: address of a buffer to load the feature list from. +Returns: -EFAULT if the given address is not accessible from kernel space. + 0 in case of success. + +2.4. ATTRIBUTE: KVM_S390_VM_CPU_PROCESSOR_FEAT (r/w) + +Allows user space to retrieve or change enabled cpu features for all VCPUs of a +VM. Features that are not available cannot be enabled. + +See 2.3. for a description of the parameter struct. + +Parameters: address of a buffer to store/load the feature list from. +Returns: -EFAULT if the given address is not accessible from kernel space. + -EINVAL if a cpu feature that is not available is to be enabled. + -EBUSY if at least one VCPU has already been defined. + 0 in case of success. + 3. GROUP: KVM_S390_VM_TOD Architectures: s390 diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index bcc20dc91ea8..b2a83a0ce42c 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -658,6 +658,8 @@ struct kvm_arch{ struct kvm_s390_cpu_model model; struct kvm_s390_crypto crypto; u64 epoch; + /* subset of available cpu features enabled by user space */ + DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); }; #define KVM_HVA_ERR_BAD (-1UL) diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 3b8e99ef9d58..a8559f265e26 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h @@ -93,6 +93,14 @@ struct kvm_s390_vm_cpu_machine { __u64 fac_list[256]; }; +#define KVM_S390_VM_CPU_PROCESSOR_FEAT 2 +#define KVM_S390_VM_CPU_MACHINE_FEAT 3 + +#define KVM_S390_VM_CPU_FEAT_NR_BITS 1024 +struct kvm_s390_vm_cpu_feat { + __u64 feat[16]; +}; + /* kvm attributes for crypto */ #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0 #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 44297ff53b44..6960468f28ad 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -132,6 +133,9 @@ unsigned long kvm_s390_fac_list_mask_size(void) return ARRAY_SIZE(kvm_s390_fac_list_mask); } +/* available cpu features supported by kvm */ +static DECLARE_BITMAP(kvm_s390_available_cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); + static struct gmap_notifier gmap_notifier; debug_info_t *kvm_s390_dbf; @@ -677,6 +681,29 @@ out: return ret; } +static int kvm_s390_set_processor_feat(struct kvm *kvm, + struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_cpu_feat data; + int ret = -EBUSY; + + if (copy_from_user(&data, (void __user *)attr->addr, sizeof(data))) + return -EFAULT; + if (!bitmap_subset((unsigned long *) data.feat, + kvm_s390_available_cpu_feat, + KVM_S390_VM_CPU_FEAT_NR_BITS)) + return -EINVAL; + + mutex_lock(&kvm->lock); + if (!atomic_read(&kvm->online_vcpus)) { + bitmap_copy(kvm->arch.cpu_feat, (unsigned long *) data.feat, + KVM_S390_VM_CPU_FEAT_NR_BITS); + ret = 0; + } + mutex_unlock(&kvm->lock); + return ret; +} + static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) { int ret = -ENXIO; @@ -685,6 +712,9 @@ static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_CPU_PROCESSOR: ret = kvm_s390_set_processor(kvm, attr); break; + case KVM_S390_VM_CPU_PROCESSOR_FEAT: + ret = kvm_s390_set_processor_feat(kvm, attr); + break; } return ret; } @@ -733,6 +763,31 @@ out: return ret; } +static int kvm_s390_get_processor_feat(struct kvm *kvm, + struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_cpu_feat data; + + bitmap_copy((unsigned long *) data.feat, kvm->arch.cpu_feat, + KVM_S390_VM_CPU_FEAT_NR_BITS); + if (copy_to_user((void __user *)attr->addr, &data, sizeof(data))) + return -EFAULT; + return 0; +} + +static int kvm_s390_get_machine_feat(struct kvm *kvm, + struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_cpu_feat data; + + bitmap_copy((unsigned long *) data.feat, + kvm_s390_available_cpu_feat, + KVM_S390_VM_CPU_FEAT_NR_BITS); + if (copy_to_user((void __user *)attr->addr, &data, sizeof(data))) + return -EFAULT; + return 0; +} + static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) { int ret = -ENXIO; @@ -744,6 +799,12 @@ static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_CPU_MACHINE: ret = kvm_s390_get_machine(kvm, attr); break; + case KVM_S390_VM_CPU_PROCESSOR_FEAT: + ret = kvm_s390_get_processor_feat(kvm, attr); + break; + case KVM_S390_VM_CPU_MACHINE_FEAT: + ret = kvm_s390_get_machine_feat(kvm, attr); + break; } return ret; } @@ -827,6 +888,8 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) switch (attr->attr) { case KVM_S390_VM_CPU_PROCESSOR: case KVM_S390_VM_CPU_MACHINE: + case KVM_S390_VM_CPU_PROCESSOR_FEAT: + case KVM_S390_VM_CPU_MACHINE_FEAT: ret = 0; break; default: diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index c5ec4d31e5e3..52aa47e112d8 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -175,6 +175,12 @@ static inline int set_kvm_facility(u64 *fac_list, unsigned long nr) return 0; } +static inline int test_kvm_cpu_feat(struct kvm *kvm, unsigned long nr) +{ + WARN_ON_ONCE(nr >= KVM_S390_VM_CPU_FEAT_NR_BITS); + return test_bit_inv(nr, kvm->arch.cpu_feat); +} + /* are cpu states controlled by user space */ static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm) { -- cgit v1.3-14-g43fede From 0a763c780b7cb830c250d00ead975778ab948f40 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 18 May 2016 16:03:47 +0200 Subject: KVM: s390: interface to query and configure cpu subfunctions We have certain instructions that indicate available subfunctions via a query subfunction (crypto functions and ptff), or via a test bit function (plo). By exposing these "subfunction blocks" to user space, we allow user space to 1) query available subfunctions and make sure subfunctions won't get lost during migration - e.g. properly indicate them via a CPU model 2) change the subfunctions to be reported to the guest (even adding unavailable ones) This mechanism works just like the way we indicate the stfl(e) list to user space. This way, user space could even emulate some subfunctions in QEMU in the future. If this is ever applicable, we have to make sure later on, that unsupported subfunctions result in an intercept to QEMU. Please note that support to indicate them to the guest is still missing and requires hardware support. Usually, the IBC takes already care of these subfunctions for migration safety. QEMU should make sure to always set these bits properly according to the machine generation to be emulated. Available subfunctions are only valid in combination with STFLE bits retrieved via KVM_S390_VM_CPU_MACHINE and enabled via KVM_S390_VM_CPU_PROCESSOR. If the applicable bits are available, the indicated subfunctions are guaranteed to be correct. Signed-off-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- Documentation/virtual/kvm/devices/vm.txt | 57 ++++++++++++++++++++ arch/s390/include/uapi/asm/kvm.h | 20 +++++++ arch/s390/kvm/kvm-s390.c | 89 ++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) (limited to 'Documentation') diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index 0ed6808b9965..8a458f42ded2 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt @@ -112,6 +112,63 @@ Returns: -EFAULT if the given address is not accessible from kernel space. -EBUSY if at least one VCPU has already been defined. 0 in case of success. +2.5. ATTRIBUTE: KVM_S390_VM_CPU_MACHINE_SUBFUNC (r/o) + +Allows user space to retrieve available cpu subfunctions without any filtering +done by a set IBC. These subfunctions are indicated to the guest VCPU via +query or "test bit" subfunctions and used e.g. by cpacf functions, plo and ptff. + +A subfunction block is only valid if KVM_S390_VM_CPU_MACHINE contains the +STFL(E) bit introducing the affected instruction. If the affected instruction +indicates subfunctions via a "query subfunction", the response block is +contained in the returned struct. If the affected instruction +indicates subfunctions via a "test bit" mechanism, the subfunction codes are +contained in the returned struct in MSB 0 bit numbering. + +struct kvm_s390_vm_cpu_subfunc { + u8 plo[32]; # always valid (ESA/390 feature) + u8 ptff[16]; # valid with TOD-clock steering + u8 kmac[16]; # valid with Message-Security-Assist + u8 kmc[16]; # valid with Message-Security-Assist + u8 km[16]; # valid with Message-Security-Assist + u8 kimd[16]; # valid with Message-Security-Assist + u8 klmd[16]; # valid with Message-Security-Assist + u8 pckmo[16]; # valid with Message-Security-Assist-Extension 3 + u8 kmctr[16]; # valid with Message-Security-Assist-Extension 4 + u8 kmf[16]; # valid with Message-Security-Assist-Extension 4 + u8 kmo[16]; # valid with Message-Security-Assist-Extension 4 + u8 pcc[16]; # valid with Message-Security-Assist-Extension 4 + u8 ppno[16]; # valid with Message-Security-Assist-Extension 5 + u8 reserved[1824]; # reserved for future instructions +}; + +Parameters: address of a buffer to load the subfunction blocks from. +Returns: -EFAULT if the given address is not accessible from kernel space. + 0 in case of success. + +2.6. ATTRIBUTE: KVM_S390_VM_CPU_PROCESSOR_SUBFUNC (r/w) + +Allows user space to retrieve or change cpu subfunctions to be indicated for +all VCPUs of a VM. This attribute will only be available if kernel and +hardware support are in place. + +The kernel uses the configured subfunction blocks for indication to +the guest. A subfunction block will only be used if the associated STFL(E) bit +has not been disabled by user space (so the instruction to be queried is +actually available for the guest). + +As long as no data has been written, a read will fail. The IBC will be used +to determine available subfunctions in this case, this will guarantee backward +compatibility. + +See 2.5. for a description of the parameter struct. + +Parameters: address of a buffer to store/load the subfunction blocks from. +Returns: -EFAULT if the given address is not accessible from kernel space. + -EINVAL when reading, if there was no write yet. + -EBUSY if at least one VCPU has already been defined. + 0 in case of success. + 3. GROUP: KVM_S390_VM_TOD Architectures: s390 diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 789c4e27e294..f0818d70d73d 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h @@ -102,6 +102,26 @@ struct kvm_s390_vm_cpu_feat { __u64 feat[16]; }; +#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC 4 +#define KVM_S390_VM_CPU_MACHINE_SUBFUNC 5 +/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */ +struct kvm_s390_vm_cpu_subfunc { + __u8 plo[32]; /* always */ + __u8 ptff[16]; /* with TOD-clock steering */ + __u8 kmac[16]; /* with MSA */ + __u8 kmc[16]; /* with MSA */ + __u8 km[16]; /* with MSA */ + __u8 kimd[16]; /* with MSA */ + __u8 klmd[16]; /* with MSA */ + __u8 pckmo[16]; /* with MSA3 */ + __u8 kmctr[16]; /* with MSA4 */ + __u8 kmf[16]; /* with MSA4 */ + __u8 kmo[16]; /* with MSA4 */ + __u8 pcc[16]; /* with MSA4 */ + __u8 ppno[16]; /* with MSA5 */ + __u8 reserved[1824]; +}; + /* kvm attributes for crypto */ #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0 #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 2b5c14da3227..f746a35e3950 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "kvm-s390.h" #include "gaccess.h" @@ -135,6 +137,8 @@ unsigned long kvm_s390_fac_list_mask_size(void) /* available cpu features supported by kvm */ static DECLARE_BITMAP(kvm_s390_available_cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); +/* available subfunctions indicated via query / "test bit" */ +static struct kvm_s390_vm_cpu_subfunc kvm_s390_available_subfunc; static struct gmap_notifier gmap_notifier; debug_info_t *kvm_s390_dbf; @@ -198,8 +202,52 @@ static void allow_cpu_feat(unsigned long nr) set_bit_inv(nr, kvm_s390_available_cpu_feat); } +static inline int plo_test_bit(unsigned char nr) +{ + register unsigned long r0 asm("0") = (unsigned long) nr | 0x100; + int cc = 3; /* subfunction not available */ + + asm volatile( + /* Parameter registers are ignored for "test bit" */ + " plo 0,0,0,0(0)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (cc) + : "d" (r0) + : "cc"); + return cc == 0; +} + static void kvm_s390_cpu_feat_init(void) { + int i; + + for (i = 0; i < 256; ++i) { + if (plo_test_bit(i)) + kvm_s390_available_subfunc.plo[i >> 3] |= 0x80 >> (i & 7); + } + + if (test_facility(28)) /* TOD-clock steering */ + etr_ptff(kvm_s390_available_subfunc.ptff, ETR_PTFF_QAF); + + if (test_facility(17)) { /* MSA */ + __cpacf_query(CPACF_KMAC, kvm_s390_available_subfunc.kmac); + __cpacf_query(CPACF_KMC, kvm_s390_available_subfunc.kmc); + __cpacf_query(CPACF_KM, kvm_s390_available_subfunc.km); + __cpacf_query(CPACF_KIMD, kvm_s390_available_subfunc.kimd); + __cpacf_query(CPACF_KLMD, kvm_s390_available_subfunc.klmd); + } + if (test_facility(76)) /* MSA3 */ + __cpacf_query(CPACF_PCKMO, kvm_s390_available_subfunc.pckmo); + if (test_facility(77)) { /* MSA4 */ + __cpacf_query(CPACF_KMCTR, kvm_s390_available_subfunc.kmctr); + __cpacf_query(CPACF_KMF, kvm_s390_available_subfunc.kmf); + __cpacf_query(CPACF_KMO, kvm_s390_available_subfunc.kmo); + __cpacf_query(CPACF_PCC, kvm_s390_available_subfunc.pcc); + } + if (test_facility(57)) /* MSA5 */ + __cpacf_query(CPACF_PPNO, kvm_s390_available_subfunc.ppno); + if (MACHINE_HAS_ESOP) allow_cpu_feat(KVM_S390_VM_CPU_FEAT_ESOP); } @@ -717,6 +765,16 @@ static int kvm_s390_set_processor_feat(struct kvm *kvm, return ret; } +static int kvm_s390_set_processor_subfunc(struct kvm *kvm, + struct kvm_device_attr *attr) +{ + /* + * Once supported by kernel + hw, we have to store the subfunctions + * in kvm->arch and remember that user space configured them. + */ + return -ENXIO; +} + static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) { int ret = -ENXIO; @@ -728,6 +786,9 @@ static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_CPU_PROCESSOR_FEAT: ret = kvm_s390_set_processor_feat(kvm, attr); break; + case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC: + ret = kvm_s390_set_processor_subfunc(kvm, attr); + break; } return ret; } @@ -801,6 +862,25 @@ static int kvm_s390_get_machine_feat(struct kvm *kvm, return 0; } +static int kvm_s390_get_processor_subfunc(struct kvm *kvm, + struct kvm_device_attr *attr) +{ + /* + * Once we can actually configure subfunctions (kernel + hw support), + * we have to check if they were already set by user space, if so copy + * them from kvm->arch. + */ + return -ENXIO; +} + +static int kvm_s390_get_machine_subfunc(struct kvm *kvm, + struct kvm_device_attr *attr) +{ + if (copy_to_user((void __user *)attr->addr, &kvm_s390_available_subfunc, + sizeof(struct kvm_s390_vm_cpu_subfunc))) + return -EFAULT; + return 0; +} static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) { int ret = -ENXIO; @@ -818,6 +898,12 @@ static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_CPU_MACHINE_FEAT: ret = kvm_s390_get_machine_feat(kvm, attr); break; + case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC: + ret = kvm_s390_get_processor_subfunc(kvm, attr); + break; + case KVM_S390_VM_CPU_MACHINE_SUBFUNC: + ret = kvm_s390_get_machine_subfunc(kvm, attr); + break; } return ret; } @@ -903,8 +989,11 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_CPU_MACHINE: case KVM_S390_VM_CPU_PROCESSOR_FEAT: case KVM_S390_VM_CPU_MACHINE_FEAT: + case KVM_S390_VM_CPU_MACHINE_SUBFUNC: ret = 0; break; + /* configuring subfunctions is not supported yet */ + case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC: default: ret = -ENXIO; break; -- cgit v1.3-14-g43fede From f9cbd9b02539330ddd349df583fcfc2db8a23b90 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 3 Mar 2016 09:48:47 +0100 Subject: KVM: s390: provide CMMA attributes only if available Let's not provide the device attribute for cmma enabling and clearing if the hardware doesn't support it. This also helps getting rid of the undocumented return value "-EINVAL" in case CMMA is not available when trying to enable it. Also properly document the meaning of -EINVAL for CMMA clearing. Reviewed-by: Christian Borntraeger Signed-off-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- Documentation/virtual/kvm/api.txt | 2 ++ Documentation/virtual/kvm/devices/vm.txt | 3 ++- arch/s390/kvm/kvm-s390.c | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index a4482cce4bae..4aac3e51bf9f 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2520,6 +2520,7 @@ Parameters: struct kvm_device_attr Returns: 0 on success, -1 on error Errors: ENXIO: The group or attribute is unknown/unsupported for this device + or hardware support is missing. EPERM: The attribute cannot (currently) be accessed this way (e.g. read-only attribute, or attribute that only makes sense when the device is in a different state) @@ -2547,6 +2548,7 @@ Parameters: struct kvm_device_attr Returns: 0 on success, -1 on error Errors: ENXIO: The group or attribute is unknown/unsupported for this device + or hardware support is missing. Tests whether a device supports a particular attribute. A successful return indicates the attribute is implemented. It does not necessarily diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index 8a458f42ded2..b6cda49f2ba4 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt @@ -20,7 +20,8 @@ Enables Collaborative Memory Management Assist (CMMA) for the virtual machine. 1.2. ATTRIBUTE: KVM_S390_VM_MEM_CLR_CMMA Parameters: none -Returns: 0 +Returns: -EINVAL if CMMA was not enabled + 0 otherwise Clear the CMMA status for all guest pages, so any pages the guest marked as unused are again used any may not be reclaimed by the host. diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 005e664f6360..f695c6e08337 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -485,7 +485,7 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att unsigned int idx; switch (attr->attr) { case KVM_S390_VM_MEM_ENABLE_CMMA: - ret = -EINVAL; + ret = -ENXIO; if (!sclp.has_cmma) break; @@ -499,6 +499,9 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att mutex_unlock(&kvm->lock); break; case KVM_S390_VM_MEM_CLR_CMMA: + ret = -ENXIO; + if (!sclp.has_cmma) + break; ret = -EINVAL; if (!kvm->arch.use_cmma) break; @@ -964,6 +967,8 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) switch (attr->attr) { case KVM_S390_VM_MEM_ENABLE_CMMA: case KVM_S390_VM_MEM_CLR_CMMA: + ret = sclp.has_cmma ? 0 : -ENXIO; + break; case KVM_S390_VM_MEM_LIMIT_SIZE: ret = 0; break; -- cgit v1.3-14-g43fede From 96d5a545374eac8fbd29b23bcd0d624c37e0ab9d Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Tue, 3 May 2016 10:56:48 -0500 Subject: ARM: dts: am437x: Add missing compatibles to PWM binding documents There are several SOC specific compatibles for ECAP, EHRPWM and PWMMS that are in use but aren't properly documented. Therefore, fix this by adding the compatibles to the appropriate binding documents. While at it make minor corrections to the binding document. Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- .../devicetree/bindings/pwm/pwm-tiecap.txt | 12 ++++++++++-- .../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 12 ++++++++++-- .../devicetree/bindings/pwm/pwm-tipwmss.txt | 21 +++++++++++++++++++-- 3 files changed, 39 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index fb81179dce37..788da6cf7074 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -2,8 +2,9 @@ TI SOC ECAP based APWM controller Required properties: - compatible: Must be "ti,-ecap". - for am33xx - compatible = "ti,am33xx-ecap"; - for da850 - compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + for am33xx - compatible = "ti,am33xx-ecap"; + for am4372 - compatible = "ti,am4372-ecap", "ti,am33xx-ecap"; + for da850 - compatible = "ti,da850-ecap", "ti,am33xx-ecap"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The PWM channel index ranges from 0 to 4. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -22,6 +23,13 @@ ecap0: ecap@0 { /* ECAP on am33xx */ ti,hwmods = "ecap0"; }; +ecap0: ecap@0 { /* ECAP on am4372 */ + compatible = "ti,am4372-ecap", "ti,am33xx-ecap"; + #pwm-cells = <3>; + reg = <0x48300100 0x80>; + ti,hwmods = "ecap0"; +}; + ecap0: ecap@0 { /* ECAP on da850 */ compatible = "ti,da850-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index 9c100b2c5b23..99b544f75f96 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -2,8 +2,9 @@ TI SOC EHRPWM based PWM controller Required properties: - compatible: Must be "ti,-ehrpwm". - for am33xx - compatible = "ti,am33xx-ehrpwm"; - for da850 - compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; + for am33xx - compatible = "ti,am33xx-ehrpwm"; + for am4372 - compatible = "ti,am4372-ehrpwm", "ti,am33xx-ehrpwm"; + for da850 - compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -22,6 +23,13 @@ ehrpwm0: ehrpwm@0 { /* EHRPWM on am33xx */ ti,hwmods = "ehrpwm0"; }; +ehrpwm0: ehrpwm@0 { /* EHRPWM on am4372 */ + compatible = "ti,am4372-ehrpwm", "ti,am33xx-ehrpwm"; + #pwm-cells = <3>; + reg = <0x48300200 0x80>; + ti,hwmods = "ehrpwm0"; +}; + ehrpwm0: ehrpwm@0 { /* EHRPWM on da850 */ compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt index f7eae77f8354..fd8e87c16a44 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt @@ -1,7 +1,10 @@ TI SOC based PWM Subsystem Required properties: -- compatible: Must be "ti,am33xx-pwmss"; +- compatible: Must be "ti,-pwmss". + for am33xx - compatible = "ti,am33xx-pwmss"; + for am4372 - compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + - reg: physical base address and size of the registers map. - address-cells: Specify the number of u32 entries needed in child nodes. Should set to 1. @@ -16,7 +19,7 @@ Required properties: Also child nodes should also populated under PWMSS DT node. Example: -pwmss0: pwmss@48300000 { +epwmss0: epwmss@48300000 { /* PWMSS for am33xx */ compatible = "ti,am33xx-pwmss"; reg = <0x48300000 0x10>; ti,hwmods = "epwmss0"; @@ -29,3 +32,17 @@ pwmss0: pwmss@48300000 { /* child nodes go here */ }; + +epwmss0: epwmss@48300000 { /* PWMSS for am4372 */ + compatible = "ti,am4372-pwmss","ti,am33xx-pwmss" + reg = <0x48300000 0x10>; + ti,hwmods = "epwmss0"; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + ranges = <0x48300100 0x48300100 0x80 /* ECAP */ + 0x48300180 0x48300180 0x80 /* EQEP */ + 0x48300200 0x48300200 0x80>; /* EHRPWM */ + + /* child nodes go here */ +}; -- cgit v1.3-14-g43fede From 956abfe38cf51f8710bc1289333c0135129cf5fd Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Tue, 3 May 2016 10:56:49 -0500 Subject: pwm: pwm-tiehrpwm: Update dt binding document to use generic node name Now that the node name has been changed from ehrpwm to pwm the document should show this proper usage. Change the unit address in the example from 0 to the proper physical address value that should be used. Also insure that the unit address matches to the reg property. Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index 99b544f75f96..f3bc09e92d4c 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -16,22 +16,22 @@ Optional properties: Example: -ehrpwm0: ehrpwm@0 { /* EHRPWM on am33xx */ +ehrpwm0: pwm@48300200 { /* EHRPWM on am33xx */ compatible = "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x100>; ti,hwmods = "ehrpwm0"; }; -ehrpwm0: ehrpwm@0 { /* EHRPWM on am4372 */ +ehrpwm0: pwm@48300200 { /* EHRPWM on am4372 */ compatible = "ti,am4372-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x80>; ti,hwmods = "ehrpwm0"; }; -ehrpwm0: ehrpwm@0 { /* EHRPWM on da850 */ +ehrpwm0: pwm@1f00000 { /* EHRPWM on da850 */ compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; - reg = <0x300000 0x2000>; + reg = <0x1f00000 0x2000>; }; -- cgit v1.3-14-g43fede From 7d68a7f8fed9925437eacf067654ee8e753f8c49 Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Tue, 3 May 2016 10:56:50 -0500 Subject: pwm: pwm-tiecap: Update dt binding document to use proper unit address Replace unit address from 0 to the proper physical address. Also insure that the unit address matches the reg property address. Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- Documentation/devicetree/bindings/pwm/pwm-tiecap.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index 788da6cf7074..0d47354b72f4 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -16,22 +16,22 @@ Optional properties: Example: -ecap0: ecap@0 { /* ECAP on am33xx */ +ecap0: ecap@48300100 { /* ECAP on am33xx */ compatible = "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; ti,hwmods = "ecap0"; }; -ecap0: ecap@0 { /* ECAP on am4372 */ +ecap0: ecap@48300100 { /* ECAP on am4372 */ compatible = "ti,am4372-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; ti,hwmods = "ecap0"; }; -ecap0: ecap@0 { /* ECAP on da850 */ +ecap0: ecap@1f06000 { /* ECAP on da850 */ compatible = "ti,da850-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; - reg = <0x306000 0x80>; + reg = <0x1f06000 0x80>; }; -- cgit v1.3-14-g43fede From 229110c1aa69134a1ca1e3118cae08fac9d843ad Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Tue, 3 May 2016 10:56:51 -0500 Subject: ARM: dts: am437x/am33xx/da850: Add new ECAP and EPWM bindings Switch to a new ECAP and EPWM bindings that doesn't depend on hwmod to provide the various required clocks. For AM437 and AM335x, add the required clocks explicitly to DT. The hwmod entries for ECAP and EPWM will be removed and this will prevent anything from breaking. Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- .../devicetree/bindings/pwm/pwm-tiecap.txt | 18 +++++--- .../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 18 +++++--- arch/arm/boot/dts/am33xx.dtsi | 30 +++++++++--- arch/arm/boot/dts/am4372.dtsi | 54 ++++++++++++++++++---- 4 files changed, 93 insertions(+), 27 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index 0d47354b72f4..ee0a8bd34701 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -2,9 +2,9 @@ TI SOC ECAP based APWM controller Required properties: - compatible: Must be "ti,-ecap". - for am33xx - compatible = "ti,am33xx-ecap"; - for am4372 - compatible = "ti,am4372-ecap", "ti,am33xx-ecap"; - for da850 - compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + for am33xx - compatible = "ti,am3352-ecap", "ti,am33xx-ecap"; + for am4372 - compatible = "ti,am4372-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; + for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The PWM channel index ranges from 0 to 4. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -13,25 +13,31 @@ Required properties: Optional properties: - ti,hwmods: Name of the hwmod associated to the ECAP: "ecap", being the 0-based instance number from the HW spec +- clocks: Handle to the ECAP's functional clock. +- clock-names: Must be set to "fck". Example: ecap0: ecap@48300100 { /* ECAP on am33xx */ - compatible = "ti,am33xx-ecap"; + compatible = "ti,am3352-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; ti,hwmods = "ecap0"; + clocks = <&l4ls_gclk>; + clock-names = "fck"; }; ecap0: ecap@48300100 { /* ECAP on am4372 */ - compatible = "ti,am4372-ecap", "ti,am33xx-ecap"; + compatible = "ti,am4372-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; ti,hwmods = "ecap0"; + clocks = <&l4ls_gclk>; + clock-names = "fck"; }; ecap0: ecap@1f06000 { /* ECAP on da850 */ - compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x1f06000 0x80>; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index f3bc09e92d4c..e9a156b56bd5 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -2,9 +2,9 @@ TI SOC EHRPWM based PWM controller Required properties: - compatible: Must be "ti,-ehrpwm". - for am33xx - compatible = "ti,am33xx-ehrpwm"; - for am4372 - compatible = "ti,am4372-ehrpwm", "ti,am33xx-ehrpwm"; - for da850 - compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; + for am33xx - compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; + for am4372 - compatible = "ti,am4372-ehrpwm", "ti-am3352-ehrpwm", "ti,am33xx-ehrpwm"; + for da850 - compatible = "ti,da850-ehrpwm", "ti-am3352-ehrpwm", "ti,am33xx-ehrpwm"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -13,25 +13,31 @@ Required properties: Optional properties: - ti,hwmods: Name of the hwmod associated to the EHRPWM: "ehrpwm", being the 0-based instance number from the HW spec +- clocks: Handle to the PWM's time-base and functional clock. +- clock-names: Must be set to "tbclk" and "fck". Example: ehrpwm0: pwm@48300200 { /* EHRPWM on am33xx */ - compatible = "ti,am33xx-ehrpwm"; + compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x100>; + clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; ti,hwmods = "ehrpwm0"; }; ehrpwm0: pwm@48300200 { /* EHRPWM on am4372 */ - compatible = "ti,am4372-ehrpwm", "ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x80>; + clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; ti,hwmods = "ehrpwm0"; }; ehrpwm0: pwm@1f00000 { /* EHRPWM on da850 */ - compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; + compatible = "ti,da850-ehrpwm", "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x1f00000 0x2000>; }; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 52be48bbd2dd..999ba2f1a8b7 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -679,9 +679,12 @@ 0x48300200 0x48300200 0x80>; /* EHRPWM */ ecap0: ecap@48300100 { - compatible = "ti,am33xx-ecap"; + compatible = "ti,am3352-ecap", + "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "fck"; interrupts = <31>; interrupt-names = "ecap0"; ti,hwmods = "ecap0"; @@ -689,10 +692,13 @@ }; ehrpwm0: pwm@48300200 { - compatible = "ti,am33xx-ehrpwm"; + compatible = "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x80>; ti,hwmods = "ehrpwm0"; + clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -709,9 +715,12 @@ 0x48302200 0x48302200 0x80>; /* EHRPWM */ ecap1: ecap@48302100 { - compatible = "ti,am33xx-ecap"; + compatible = "ti,am3352-ecap", + "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48302100 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "fck"; interrupts = <47>; interrupt-names = "ecap1"; ti,hwmods = "ecap1"; @@ -719,10 +728,13 @@ }; ehrpwm1: pwm@48302200 { - compatible = "ti,am33xx-ehrpwm"; + compatible = "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48302200 0x80>; ti,hwmods = "ehrpwm1"; + clocks = <&ehrpwm1_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -739,9 +751,12 @@ 0x48304200 0x48304200 0x80>; /* EHRPWM */ ecap2: ecap@48304100 { - compatible = "ti,am33xx-ecap"; + compatible = "ti,am3352-ecap", + "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48304100 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "fck"; interrupts = <61>; interrupt-names = "ecap2"; ti,hwmods = "ecap2"; @@ -749,10 +764,13 @@ }; ehrpwm2: pwm@48304200 { - compatible = "ti,am33xx-ehrpwm"; + compatible = "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48304200 0x80>; ti,hwmods = "ehrpwm2"; + clocks = <&ehrpwm2_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 12fcde4d4d2e..e8584606d56f 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -672,18 +672,26 @@ status = "disabled"; ecap0: ecap@48300100 { - compatible = "ti,am4372-ecap","ti,am33xx-ecap"; + compatible = "ti,am4372-ecap", + "ti,am3352-ecap", + "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; ti,hwmods = "ecap0"; + clocks = <&l4ls_gclk>; + clock-names = "fck"; status = "disabled"; }; ehrpwm0: pwm@48300200 { - compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", + "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x80>; ti,hwmods = "ehrpwm0"; + clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -698,18 +706,26 @@ status = "disabled"; ecap1: ecap@48302100 { - compatible = "ti,am4372-ecap","ti,am33xx-ecap"; + compatible = "ti,am4372-ecap", + "ti,am3352-ecap", + "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48302100 0x80>; ti,hwmods = "ecap1"; + clocks = <&l4ls_gclk>; + clock-names = "fck"; status = "disabled"; }; ehrpwm1: pwm@48302200 { - compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", + "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48302200 0x80>; ti,hwmods = "ehrpwm1"; + clocks = <&ehrpwm1_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -724,18 +740,26 @@ status = "disabled"; ecap2: ecap@48304100 { - compatible = "ti,am4372-ecap","ti,am33xx-ecap"; + compatible = "ti,am4372-ecap", + "ti,am3352-ecap", + "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48304100 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "fck"; ti,hwmods = "ecap2"; status = "disabled"; }; ehrpwm2: pwm@48304200 { - compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", + "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48304200 0x80>; ti,hwmods = "ehrpwm2"; + clocks = <&ehrpwm2_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -750,10 +774,14 @@ status = "disabled"; ehrpwm3: pwm@48306200 { - compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", + "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48306200 0x80>; ti,hwmods = "ehrpwm3"; + clocks = <&ehrpwm3_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -768,10 +796,14 @@ status = "disabled"; ehrpwm4: pwm@48308200 { - compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", + "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48308200 0x80>; ti,hwmods = "ehrpwm4"; + clocks = <&ehrpwm4_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; status = "disabled"; }; }; @@ -786,9 +818,13 @@ status = "disabled"; ehrpwm5: pwm@4830a200 { - compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; + compatible = "ti,am4372-ehrpwm", + "ti,am3352-ehrpwm", + "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x4830a200 0x80>; + clocks = <&ehrpwm5_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; ti,hwmods = "ehrpwm5"; status = "disabled"; }; -- cgit v1.3-14-g43fede From 58bfbea5b1c6826953d54ee470ab560aba55afce Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Tue, 3 May 2016 10:56:53 -0500 Subject: ARM: dts: am437x/am33xx: Remove hwmod entries for ECAP and EPWM nodes Previous patches switched the ECAP and EPWM to use the new bindings. These bindings explicitly adds the various required clocks via DT rather than depending on hwmod. Therefore, it is safe to remove the hwmod entries since they are no longer needed. Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Acked-by: Paul Walmsley Signed-off-by: Tony Lindgren --- Documentation/devicetree/bindings/pwm/pwm-tiecap.txt | 3 --- Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt | 3 --- arch/arm/boot/dts/am33xx.dtsi | 6 ------ arch/arm/boot/dts/am4372.dtsi | 9 --------- 4 files changed, 21 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index ee0a8bd34701..f2a9a7cbea34 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -11,8 +11,6 @@ Required properties: - reg: physical base address and size of the registers map. Optional properties: -- ti,hwmods: Name of the hwmod associated to the ECAP: - "ecap", being the 0-based instance number from the HW spec - clocks: Handle to the ECAP's functional clock. - clock-names: Must be set to "fck". @@ -22,7 +20,6 @@ ecap0: ecap@48300100 { /* ECAP on am33xx */ compatible = "ti,am3352-ecap", "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; - ti,hwmods = "ecap0"; clocks = <&l4ls_gclk>; clock-names = "fck"; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index e9a156b56bd5..41a2bd4b9fe3 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -11,8 +11,6 @@ Required properties: - reg: physical base address and size of the registers map. Optional properties: -- ti,hwmods: Name of the hwmod associated to the EHRPWM: - "ehrpwm", being the 0-based instance number from the HW spec - clocks: Handle to the PWM's time-base and functional clock. - clock-names: Must be set to "tbclk" and "fck". @@ -24,7 +22,6 @@ ehrpwm0: pwm@48300200 { /* EHRPWM on am33xx */ reg = <0x48300200 0x100>; clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; - ti,hwmods = "ehrpwm0"; }; ehrpwm0: pwm@48300200 { /* EHRPWM on am4372 */ diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 999ba2f1a8b7..2661accdcd92 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -687,7 +687,6 @@ clock-names = "fck"; interrupts = <31>; interrupt-names = "ecap0"; - ti,hwmods = "ecap0"; status = "disabled"; }; @@ -696,7 +695,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x80>; - ti,hwmods = "ehrpwm0"; clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -723,7 +721,6 @@ clock-names = "fck"; interrupts = <47>; interrupt-names = "ecap1"; - ti,hwmods = "ecap1"; status = "disabled"; }; @@ -732,7 +729,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48302200 0x80>; - ti,hwmods = "ehrpwm1"; clocks = <&ehrpwm1_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -759,7 +755,6 @@ clock-names = "fck"; interrupts = <61>; interrupt-names = "ecap2"; - ti,hwmods = "ecap2"; status = "disabled"; }; @@ -768,7 +763,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48304200 0x80>; - ti,hwmods = "ehrpwm2"; clocks = <&ehrpwm2_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index e8584606d56f..cfdd4b77f714 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -677,7 +677,6 @@ "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; - ti,hwmods = "ecap0"; clocks = <&l4ls_gclk>; clock-names = "fck"; status = "disabled"; @@ -689,7 +688,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x80>; - ti,hwmods = "ehrpwm0"; clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -711,7 +709,6 @@ "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48302100 0x80>; - ti,hwmods = "ecap1"; clocks = <&l4ls_gclk>; clock-names = "fck"; status = "disabled"; @@ -723,7 +720,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48302200 0x80>; - ti,hwmods = "ehrpwm1"; clocks = <&ehrpwm1_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -747,7 +743,6 @@ reg = <0x48304100 0x80>; clocks = <&l4ls_gclk>; clock-names = "fck"; - ti,hwmods = "ecap2"; status = "disabled"; }; @@ -757,7 +752,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48304200 0x80>; - ti,hwmods = "ehrpwm2"; clocks = <&ehrpwm2_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -779,7 +773,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48306200 0x80>; - ti,hwmods = "ehrpwm3"; clocks = <&ehrpwm3_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -801,7 +794,6 @@ "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48308200 0x80>; - ti,hwmods = "ehrpwm4"; clocks = <&ehrpwm4_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; status = "disabled"; @@ -825,7 +817,6 @@ reg = <0x4830a200 0x80>; clocks = <&ehrpwm5_tbclk>, <&l4ls_gclk>; clock-names = "tbclk", "fck"; - ti,hwmods = "ehrpwm5"; status = "disabled"; }; }; -- cgit v1.3-14-g43fede From 34370142331953146efd1be573696785957a2fa9 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Tue, 3 May 2016 10:56:55 -0500 Subject: ARM: dts: DRA7: Add dt nodes for PWMSS Add PWMSS device tree nodes for DRA7 SoC family and add documentation for dt bindings. Signed-off-by: Vignesh R [fcooper@ti.com: Add eCAP and use updated bindings for PWMSS and ePWM] Signed-off-by: Franklin S Cooper Jr Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- .../devicetree/bindings/pwm/pwm-tiecap.txt | 9 +++ .../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 9 +++ .../devicetree/bindings/pwm/pwm-tipwmss.txt | 12 +++ arch/arm/boot/dts/dra7.dtsi | 90 ++++++++++++++++++++++ 4 files changed, 120 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index f2a9a7cbea34..8007e839a716 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -5,6 +5,7 @@ Required properties: for am33xx - compatible = "ti,am3352-ecap", "ti,am33xx-ecap"; for am4372 - compatible = "ti,am4372-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; + for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The PWM channel index ranges from 0 to 4. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -38,3 +39,11 @@ ecap0: ecap@1f06000 { /* ECAP on da850 */ #pwm-cells = <3>; reg = <0x1f06000 0x80>; }; + +ecap0: ecap@4843e100 { + compatible = "ti,dra746-ecap", "ti,am3352-ecap"; + #pwm-cells = <3>; + reg = <0x4843e100 0x80>; + clocks = <&l4_root_clk_div>; + clock-names = "fck"; +}; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index 41a2bd4b9fe3..944fe356bb45 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -5,6 +5,7 @@ Required properties: for am33xx - compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; for am4372 - compatible = "ti,am4372-ehrpwm", "ti-am3352-ehrpwm", "ti,am33xx-ehrpwm"; for da850 - compatible = "ti,da850-ehrpwm", "ti-am3352-ehrpwm", "ti,am33xx-ehrpwm"; + for dra746 - compatible = "ti,dra746-ehrpwm", "ti-am3352-ehrpwm"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. @@ -38,3 +39,11 @@ ehrpwm0: pwm@1f00000 { /* EHRPWM on da850 */ #pwm-cells = <3>; reg = <0x1f00000 0x2000>; }; + +ehrpwm0: pwm@4843e200 { /* EHRPWM on dra746 */ + compatible = "ti,dra746-ehrpwm", "ti,am3352-ehrpwm"; + #pwm-cells = <3>; + reg = <0x4843e200 0x80>; + clocks = <&ehrpwm0_tbclk>, <&l4_root_clk_div>; + clock-names = "tbclk", "fck"; +}; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt index fd8e87c16a44..1a5d7b71db89 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Must be "ti,-pwmss". for am33xx - compatible = "ti,am33xx-pwmss"; for am4372 - compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; + for dra746 - compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss" - reg: physical base address and size of the registers map. - address-cells: Specify the number of u32 entries needed in child nodes. @@ -46,3 +47,14 @@ epwmss0: epwmss@48300000 { /* PWMSS for am4372 */ /* child nodes go here */ }; + +epwmss0: epwmss@4843e000 { /* PWMSS for DRA7xx */ + compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"; + reg = <0x4843e000 0x30>; + ti,hwmods = "epwmss0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* child nodes go here */ +}; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index e0074014385a..5a21e46ce487 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -1743,6 +1743,96 @@ clock-names = "fck", "sys_clk"; }; }; + + epwmss0: epwmss@4843e000 { + compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"; + reg = <0x4843e000 0x30>; + ti,hwmods = "epwmss0"; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + ranges; + + ehrpwm0: pwm@4843e200 { + compatible = "ti,dra746-ehrpwm", + "ti,am3352-ehrpwm"; + #pwm-cells = <3>; + reg = <0x4843e200 0x80>; + clocks = <&ehrpwm0_tbclk>, <&l4_root_clk_div>; + clock-names = "tbclk", "fck"; + status = "disabled"; + }; + + ecap0: ecap@4843e100 { + compatible = "ti,dra746-ecap", + "ti,am3352-ecap"; + #pwm-cells = <3>; + reg = <0x4843e100 0x80>; + clocks = <&l4_root_clk_div>; + clock-names = "fck"; + status = "disabled"; + }; + }; + + epwmss1: epwmss@48440000 { + compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"; + reg = <0x48440000 0x30>; + ti,hwmods = "epwmss1"; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + ranges; + + ehrpwm1: pwm@48440200 { + compatible = "ti,dra746-ehrpwm", + "ti,am3352-ehrpwm"; + #pwm-cells = <3>; + reg = <0x48440200 0x80>; + clocks = <&ehrpwm1_tbclk>, <&l4_root_clk_div>; + clock-names = "tbclk", "fck"; + status = "disabled"; + }; + + ecap1: ecap@48440100 { + compatible = "ti,dra746-ecap", + "ti,am3352-ecap"; + #pwm-cells = <3>; + reg = <0x48440100 0x80>; + clocks = <&l4_root_clk_div>; + clock-names = "fck"; + status = "disabled"; + }; + }; + + epwmss2: epwmss@48442000 { + compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"; + reg = <0x48442000 0x30>; + ti,hwmods = "epwmss2"; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + ranges; + + ehrpwm2: pwm@48442200 { + compatible = "ti,dra746-ehrpwm", + "ti,am3352-ehrpwm"; + #pwm-cells = <3>; + reg = <0x48442200 0x80>; + clocks = <&ehrpwm2_tbclk>, <&l4_root_clk_div>; + clock-names = "tbclk", "fck"; + status = "disabled"; + }; + + ecap2: ecap@48442100 { + compatible = "ti,dra746-ecap", + "ti,am3352-ecap"; + #pwm-cells = <3>; + reg = <0x48442100 0x80>; + clocks = <&l4_root_clk_div>; + clock-names = "fck"; + status = "disabled"; + }; + }; }; thermal_zones: thermal-zones { -- cgit v1.3-14-g43fede From a5206553bab2a7d5777e0fdfb5ac8c534a28f15a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 24 May 2016 17:20:28 -0400 Subject: ARM: dts: Correct misspelling, "emda3" -> "edma3" Correct misspelling, "emda3" -> "edma3". Reported-by: Adam J Allison Signed-off-by: Robert P. J. Day Acked-by: Rob Herring Acked-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- Documentation/devicetree/bindings/dma/ti-edma.txt | 4 ++-- arch/arm/boot/dts/am33xx.dtsi | 2 +- arch/arm/boot/dts/am4372.dtsi | 2 +- arch/arm/boot/dts/dm814x.dtsi | 2 +- arch/arm/boot/dts/dra7.dtsi | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt index 079b42a81d7c..18090e7226b4 100644 --- a/Documentation/devicetree/bindings/dma/ti-edma.txt +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -15,7 +15,7 @@ Required properties: - reg: Memory map of eDMA CC - reg-names: "edma3_cc" - interrupts: Interrupt lines for CCINT, MPERR and CCERRINT. -- interrupt-names: "edma3_ccint", "emda3_mperr" and "edma3_ccerrint" +- interrupt-names: "edma3_ccint", "edma3_mperr" and "edma3_ccerrint" - ti,tptcs: List of TPTCs associated with the eDMA in the following form: <&tptc_phandle TC_priority_number>. The highest priority is 0. @@ -48,7 +48,7 @@ edma: edma@49000000 { reg = <0x49000000 0x10000>; reg-names = "edma3_cc"; interrupts = <12 13 14>; - interrupt-names = "edma3_ccint", "emda3_mperr", "edma3_ccerrint"; + interrupt-names = "edma3_ccint", "edma3_mperr", "edma3_ccerrint"; dma-requests = <64>; #dma-cells = <2>; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 2625414b805a..af18c4738bef 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -249,7 +249,7 @@ reg = <0x49000000 0x10000>; reg-names = "edma3_cc"; interrupts = <12 13 14>; - interrupt-names = "edma3_ccint", "emda3_mperr", + interrupt-names = "edma3_ccint", "edma3_mperr", "edma3_ccerrint"; dma-requests = <64>; #dma-cells = <2>; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 5a065b8eb4b6..03514665a5f5 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -238,7 +238,7 @@ interrupts = , , ; - interrupt-names = "edma3_ccint", "emda3_mperr", + interrupt-names = "edma3_ccint", "edma3_mperr", "edma3_ccerrint"; dma-requests = <64>; #dma-cells = <2>; diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi index d4537dc61497..a6e0aebc617b 100644 --- a/arch/arm/boot/dts/dm814x.dtsi +++ b/arch/arm/boot/dts/dm814x.dtsi @@ -448,7 +448,7 @@ reg = <0x49000000 0x10000>; reg-names = "edma3_cc"; interrupts = <12 13 14>; - interrupt-names = "edma3_ccint", "emda3_mperr", + interrupt-names = "edma3_ccint", "edma3_mperr", "edma3_ccerrint"; dma-requests = <64>; #dma-cells = <2>; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index c3e67eeee8e0..5f1e0296b3fd 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -436,7 +436,7 @@ interrupts = , , ; - interrupt-names = "edma3_ccint", "emda3_mperr", + interrupt-names = "edma3_ccint", "edma3_mperr", "edma3_ccerrint"; dma-requests = <64>; #dma-cells = <2>; -- cgit v1.3-14-g43fede From 03d35d9ec4ae50afeafc3ab26d8207b7069f3cba Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jun 2016 12:13:56 +0300 Subject: Documentation/sphinx: add support for specifying extra export files Let the user specify file patterns where to look for the EXPORT_SYMBOLs in addition to the file with kernel-doc comments. This is directly based on the -export-file FILE option added to kernel-doc in "kernel-doc: add support for specifying extra files for EXPORT_SYMBOLs", but we extend that with globbing patterns in the Sphinx extension. The file patterns are added as options to the :export: and :internal: arguments of the kernel-doc directive. For example, to extract the documentation of exported functions from include/net/mac80211.h: .. kernel-doc:: include/net/mac80211.h :export: net/mac80211/*.c Without the file pattern, no exported functions would be found, as the EXPORT_SYMBOLs are placed in the various source files under net/mac80211. The matched files are also added as dependencies on the document in Sphinx, as they may affect the output. This is one of the reasons to do the globbing in the Sphinx extension instead of in scripts/kernel-doc. The file pattern remains optional, and is not needed if the kernel-doc comments and EXPORT_SYMBOLs are placed in the source file passed in as the main argument to the kernel-doc directive. This is the most common case across the kernel source tree. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index d6a76f9a0ba5..dedb24e3bb7a 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -31,6 +31,7 @@ import os import subprocess import sys import re +import glob from docutils import nodes, statemachine from docutils.statemachine import ViewList @@ -44,8 +45,8 @@ class KernelDocDirective(Directive): option_spec = { 'doc': directives.unchanged_required, 'functions': directives.unchanged_required, - 'export': directives.flag, - 'internal': directives.flag, + 'export': directives.unchanged, + 'internal': directives.unchanged, } has_content = False @@ -54,6 +55,7 @@ class KernelDocDirective(Directive): cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] + export_file_patterns = [] # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) @@ -63,14 +65,21 @@ class KernelDocDirective(Directive): # FIXME: make this nicer and more robust against errors if 'export' in self.options: cmd += ['-export'] + export_file_patterns = str(self.options.get('export')).split() elif 'internal' in self.options: cmd += ['-internal'] + export_file_patterns = str(self.options.get('internal')).split() elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'functions' in self.options: for f in str(self.options.get('functions')).split(): cmd += ['-function', f] + for pattern in export_file_patterns: + for f in glob.glob(env.config.kerneldoc_srctree + '/' + pattern): + env.note_dependency(os.path.abspath(f)) + cmd += ['-export-file', f] + cmd += [filename] try: -- cgit v1.3-14-g43fede From 1a366fe9153f445e950a7a344932b7419aa83094 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 8 Jun 2016 10:21:25 +0100 Subject: pwm: sysfs: Add PWM capture support Allow a user to read PWM capture results from sysfs. To start a capture and read the result, simply read the file: $ cat $PWMCHIP/capture The output format is " ". Signed-off-by: Lee Jones Signed-off-by: Thierry Reding --- Documentation/ABI/testing/sysfs-class-pwm | 9 +++++++++ drivers/pwm/sysfs.c | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-pwm b/Documentation/ABI/testing/sysfs-class-pwm index c479d77b67c5..c20e61354561 100644 --- a/Documentation/ABI/testing/sysfs-class-pwm +++ b/Documentation/ABI/testing/sysfs-class-pwm @@ -77,3 +77,12 @@ Description: Enable/disable the PWM signal. 0 is disabled 1 is enabled + +What: /sys/class/pwm/pwmchipN/pwmX/capture +Date: June 2016 +KernelVersion: 4.8 +Contact: Lee Jones +Description: + Capture information about a PWM signal. The output format is a + pair unsigned integers (period and duty cycle), separated by a + single space. diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index d98599249a05..c3b1b563480e 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -208,16 +208,33 @@ static ssize_t polarity_store(struct device *child, return ret ? : size; } +static ssize_t capture_show(struct device *child, + struct device_attribute *attr, + char *buf) +{ + struct pwm_device *pwm = child_to_pwm_device(child); + struct pwm_capture result; + int ret; + + ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ)); + if (ret) + return ret; + + return sprintf(buf, "%u %u\n", result.period, result.duty_cycle); +} + static DEVICE_ATTR_RW(period); static DEVICE_ATTR_RW(duty_cycle); static DEVICE_ATTR_RW(enable); static DEVICE_ATTR_RW(polarity); +static DEVICE_ATTR_RO(capture); static struct attribute *pwm_attrs[] = { &dev_attr_period.attr, &dev_attr_duty_cycle.attr, &dev_attr_enable.attr, &dev_attr_polarity.attr, + &dev_attr_capture.attr, NULL }; ATTRIBUTE_GROUPS(pwm); -- cgit v1.3-14-g43fede From 5b8090747a1186f8f6a1d3a7e49f792b13ab7b84 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Fri, 10 Jun 2016 16:55:59 +0200 Subject: drm: Add helper for simple display pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provides helper functions for drivers that have a simple display pipeline. Plane, crtc and encoder are collapsed into one entity. Changes since v4: - Remove drm_connector_register() call - Forgot to assign pipe->connector Changes since v3: - (struct drm_simple_display_pipe *)->funcs should be const Changes since v2: - Drop Kconfig knob DRM_KMS_HELPER - Expand documentation Changes since v1: - Add DOC header and add to gpu.tmpl - Fix docs: @funcs is optional, "negative error code", "This hook is optional." - Add checks to drm_simple_kms_plane_atomic_check() Cc: jsarha@ti.com Signed-off-by: Noralf Trønnes Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465570559-14238-1-git-send-email-noralf@tronnes.org --- Documentation/DocBook/gpu.tmpl | 6 + drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/drm_simple_kms_helper.c | 205 ++++++++++++++++++++++++++++++++ include/drm/drm_simple_kms_helper.h | 94 +++++++++++++++ 4 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/drm_simple_kms_helper.c create mode 100644 include/drm/drm_simple_kms_helper.h (limited to 'Documentation') diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 89585ad69a4b..d09536c91717 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1688,6 +1688,12 @@ void intel_crt_init(struct drm_device *dev) !Edrivers/gpu/drm/drm_panel.c !Pdrivers/gpu/drm/drm_panel.c drm panel + + Simple KMS Helper Reference +!Iinclude/drm/drm_simple_kms_helper.h +!Edrivers/gpu/drm/drm_simple_kms_helper.c +!Pdrivers/gpu/drm/drm_simple_kms_helper.c overview + diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index aa24af35c068..e3dba6f44a79 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -23,7 +23,8 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ - drm_kms_helper_common.o drm_dp_dual_mode_helper.o + drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ + drm_simple_kms_helper.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c new file mode 100644 index 000000000000..b2071d495ada --- /dev/null +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * DOC: overview + * + * This helper library provides helpers for drivers for simple display + * hardware. + * + * drm_simple_display_pipe_init() initializes a simple display pipeline + * which has only one full-screen scanout buffer feeding one output. The + * pipeline is represented by struct &drm_simple_display_pipe and binds + * together &drm_plane, &drm_crtc and &drm_encoder structures into one fixed + * entity. Some flexibility for code reuse is provided through a separately + * allocated &drm_connector object and supporting optional &drm_bridge + * encoder drivers. + */ + +static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc) +{ + struct drm_simple_display_pipe *pipe; + + pipe = container_of(crtc, struct drm_simple_display_pipe, crtc); + if (!pipe->funcs || !pipe->funcs->enable) + return; + + pipe->funcs->enable(pipe, crtc->state); +} + +static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc) +{ + struct drm_simple_display_pipe *pipe; + + pipe = container_of(crtc, struct drm_simple_display_pipe, crtc); + if (!pipe->funcs || !pipe->funcs->disable) + return; + + pipe->funcs->disable(pipe); +} + +static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = { + .disable = drm_simple_kms_crtc_disable, + .enable = drm_simple_kms_crtc_enable, +}; + +static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +}; + +static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *plane_state) +{ + struct drm_rect src = { + .x1 = plane_state->src_x, + .y1 = plane_state->src_y, + .x2 = plane_state->src_x + plane_state->src_w, + .y2 = plane_state->src_y + plane_state->src_h, + }; + struct drm_rect dest = { + .x1 = plane_state->crtc_x, + .y1 = plane_state->crtc_y, + .x2 = plane_state->crtc_x + plane_state->crtc_w, + .y2 = plane_state->crtc_y + plane_state->crtc_h, + }; + struct drm_rect clip = { 0 }; + struct drm_simple_display_pipe *pipe; + struct drm_crtc_state *crtc_state; + bool visible; + int ret; + + pipe = container_of(plane, struct drm_simple_display_pipe, plane); + crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state, + &pipe->crtc); + if (crtc_state->enable != !!plane_state->crtc) + return -EINVAL; /* plane must match crtc enable state */ + + if (!crtc_state->enable) + return 0; /* nothing to check when disabling or disabled */ + + clip.x2 = crtc_state->adjusted_mode.hdisplay; + clip.y2 = crtc_state->adjusted_mode.vdisplay; + ret = drm_plane_helper_check_update(plane, &pipe->crtc, + plane_state->fb, + &src, &dest, &clip, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + false, true, &visible); + if (ret) + return ret; + + if (!visible) + return -EINVAL; + + if (!pipe->funcs || !pipe->funcs->check) + return 0; + + return pipe->funcs->check(pipe, plane_state, crtc_state); +} + +static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *pstate) +{ + struct drm_simple_display_pipe *pipe; + + pipe = container_of(plane, struct drm_simple_display_pipe, plane); + if (!pipe->funcs || !pipe->funcs->update) + return; + + pipe->funcs->update(pipe, pstate); +} + +static const struct drm_plane_helper_funcs drm_simple_kms_plane_helper_funcs = { + .atomic_check = drm_simple_kms_plane_atomic_check, + .atomic_update = drm_simple_kms_plane_atomic_update, +}; + +static const struct drm_plane_funcs drm_simple_kms_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +}; + +/** + * drm_simple_display_pipe_init - Initialize a simple display pipeline + * @dev: DRM device + * @pipe: simple display pipe object to initialize + * @funcs: callbacks for the display pipe (optional) + * @formats: array of supported formats (%DRM_FORMAT_*) + * @format_count: number of elements in @formats + * @connector: connector to attach and register + * + * Sets up a display pipeline which consist of a really simple + * plane-crtc-encoder pipe coupled with the provided connector. + * Teardown of a simple display pipe is all handled automatically by the drm + * core through calling drm_mode_config_cleanup(). Drivers afterwards need to + * release the memory for the structure themselves. + * + * Returns: + * Zero on success, negative error code on failure. + */ +int drm_simple_display_pipe_init(struct drm_device *dev, + struct drm_simple_display_pipe *pipe, + const struct drm_simple_display_pipe_funcs *funcs, + const uint32_t *formats, unsigned int format_count, + struct drm_connector *connector) +{ + struct drm_encoder *encoder = &pipe->encoder; + struct drm_plane *plane = &pipe->plane; + struct drm_crtc *crtc = &pipe->crtc; + int ret; + + pipe->connector = connector; + pipe->funcs = funcs; + + drm_plane_helper_add(plane, &drm_simple_kms_plane_helper_funcs); + ret = drm_universal_plane_init(dev, plane, 0, + &drm_simple_kms_plane_funcs, + formats, format_count, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) + return ret; + + drm_crtc_helper_add(crtc, &drm_simple_kms_crtc_helper_funcs); + ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, + &drm_simple_kms_crtc_funcs, NULL); + if (ret) + return ret; + + encoder->possible_crtcs = 1 << drm_crtc_index(crtc); + ret = drm_encoder_init(dev, encoder, &drm_simple_kms_encoder_funcs, + DRM_MODE_ENCODER_NONE, NULL); + if (ret) + return ret; + + return drm_mode_connector_attach_encoder(connector, encoder); +} +EXPORT_SYMBOL(drm_simple_display_pipe_init); + +MODULE_LICENSE("GPL"); diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h new file mode 100644 index 000000000000..269039722f91 --- /dev/null +++ b/include/drm/drm_simple_kms_helper.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_DRM_SIMPLE_KMS_HELPER_H +#define __LINUX_DRM_SIMPLE_KMS_HELPER_H + +struct drm_simple_display_pipe; + +/** + * struct drm_simple_display_pipe_funcs - helper operations for a simple + * display pipeline + */ +struct drm_simple_display_pipe_funcs { + /** + * @enable: + * + * This function should be used to enable the pipeline. + * It is called when the underlying crtc is enabled. + * This hook is optional. + */ + void (*enable)(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state); + /** + * @disable: + * + * This function should be used to disable the pipeline. + * It is called when the underlying crtc is disabled. + * This hook is optional. + */ + void (*disable)(struct drm_simple_display_pipe *pipe); + + /** + * @check: + * + * This function is called in the check phase of an atomic update, + * specifically when the underlying plane is checked. + * The simple display pipeline helpers already check that the plane is + * not scaled, fills the entire visible area and is always enabled + * when the crtc is also enabled. + * This hook is optional. + * + * RETURNS: + * + * 0 on success, -EINVAL if the state or the transition can't be + * supported, -ENOMEM on memory allocation failure and -EDEADLK if an + * attempt to obtain another state object ran into a &drm_modeset_lock + * deadlock. + */ + int (*check)(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state, + struct drm_crtc_state *crtc_state); + /** + * @update: + * + * This function is called when the underlying plane state is updated. + * This hook is optional. + */ + void (*update)(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state); +}; + +/** + * struct drm_simple_display_pipe - simple display pipeline + * @crtc: CRTC control structure + * @plane: Plane control structure + * @encoder: Encoder control structure + * @connector: Connector control structure + * @funcs: Pipeline control functions (optional) + * + * Simple display pipeline with plane, crtc and encoder collapsed into one + * entity. It should be initialized by calling drm_simple_display_pipe_init(). + */ +struct drm_simple_display_pipe { + struct drm_crtc crtc; + struct drm_plane plane; + struct drm_encoder encoder; + struct drm_connector *connector; + + const struct drm_simple_display_pipe_funcs *funcs; +}; + +int drm_simple_display_pipe_init(struct drm_device *dev, + struct drm_simple_display_pipe *pipe, + const struct drm_simple_display_pipe_funcs *funcs, + const uint32_t *formats, unsigned int format_count, + struct drm_connector *connector); + +#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ -- cgit v1.3-14-g43fede From 6deb2087b8683cb64362b7ff0eeba8df0bf5a07d Mon Sep 17 00:00:00 2001 From: Pramod Kumar Date: Fri, 10 Jun 2016 11:03:46 +0530 Subject: binding: Make "mdio-parent-bus" property from mandatory to optional Change "mdio-parent-bus" from mandatory section to optional as it won't be required by integrated MDIO multiplexer which has bus selection and mdio transaction generation logic, integrated inside. Signed-off-by: Pramod Kumar Reviewed-by: Andrew Lunn Acked-by: Rob Herring Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/mdio-mux.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/mdio-mux.txt b/Documentation/devicetree/bindings/net/mdio-mux.txt index 491f5bd55203..f58571f36570 100644 --- a/Documentation/devicetree/bindings/net/mdio-mux.txt +++ b/Documentation/devicetree/bindings/net/mdio-mux.txt @@ -5,11 +5,12 @@ numbered uniquely in a device dependent manner. The nodes for an MDIO bus multiplexer/switch will have one child node for each child bus. Required properties: -- mdio-parent-bus : phandle to the parent MDIO bus. - #address-cells = <1>; - #size-cells = <0>; Optional properties: +- mdio-parent-bus : phandle to the parent MDIO bus. + - Other properties specific to the multiplexer/switch hardware. Required properties for child nodes: -- cgit v1.3-14-g43fede From ce8d5dbfd64f6ca84e2fe55a0066ec8b22601567 Mon Sep 17 00:00:00 2001 From: Pramod Kumar Date: Fri, 10 Jun 2016 11:03:47 +0530 Subject: binding: mdio-mux: Add DT binding doc for Broadcom MDIO bus multiplexer Add DT binding doc for Broadcom MDIO bus multiplexer driver. Reviewed-by: Andrew Lunn Signed-off-by: Pramod Kumar Reviewed-by: Florian Fainelli Acked-by: Rob Herring Signed-off-by: David S. Miller --- .../bindings/net/brcm,mdio-mux-iproc.txt | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt b/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt new file mode 100644 index 000000000000..dfe287a5d6f2 --- /dev/null +++ b/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt @@ -0,0 +1,59 @@ +Properties for an MDIO bus multiplexer found in Broadcom iProc based SoCs. + +This MDIO bus multiplexer defines buses that could be internal as well as +external to SoCs and could accept MDIO transaction compatible to C-22 or +C-45 Clause. When child bus is selected, one needs to select these two +properties as well to generate desired MDIO transaction on appropriate bus. + +Required properties in addition to the generic multiplexer properties: + +MDIO multiplexer node: +- compatible: brcm,mdio-mux-iproc. + +Every non-ethernet PHY requires a compatible so that it could be probed based +on this compatible string. + +Additional information regarding generic multiplexer properties can be found +at- Documentation/devicetree/bindings/net/mdio-mux.txt + + +for example: + mdio_mux_iproc: mdio-mux@6602023c { + compatible = "brcm,mdio-mux-iproc"; + reg = <0x6602023c 0x14>; + #address-cells = <1>; + #size-cells = <0>; + + mdio@0 { + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + pci_phy0: pci-phy@0 { + compatible = "brcm,ns2-pcie-phy"; + reg = <0x0>; + #phy-cells = <0>; + }; + }; + + mdio@7 { + reg = <0x7>; + #address-cells = <1>; + #size-cells = <0>; + + pci_phy1: pci-phy@0 { + compatible = "brcm,ns2-pcie-phy"; + reg = <0x0>; + #phy-cells = <0>; + }; + }; + mdio@10 { + reg = <0x10>; + #address-cells = <1>; + #size-cells = <0>; + + gphy0: eth-phy@10 { + reg = <0x10>; + }; + }; + }; -- cgit v1.3-14-g43fede From 464e3b4b118f5c7abfdb68f3628df0ca65d28948 Mon Sep 17 00:00:00 2001 From: Pramod Kumar Date: Fri, 10 Jun 2016 11:03:50 +0530 Subject: binding: PHY: Binding doc for NS2 PCIe PHYs. Binding doc for NS2 PCIe PHYs. Signed-off-by: Pramod Kumar Signed-off-by: Jon Mason Acked-by: Rob Herring Signed-off-by: David S. Miller --- .../bindings/phy/brcm,mdio-mux-bus-pci.txt | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/brcm,mdio-mux-bus-pci.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/brcm,mdio-mux-bus-pci.txt b/Documentation/devicetree/bindings/phy/brcm,mdio-mux-bus-pci.txt new file mode 100644 index 000000000000..5b51007c6f24 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/brcm,mdio-mux-bus-pci.txt @@ -0,0 +1,27 @@ +* Broadcom NS2 PCIe PHY binding document + +Required bus properties: +- reg: MDIO Bus number for the MDIO interface +- #address-cells: must be 1 +- #size-cells: must be 0 + +Required PHY properties: +- compatible: should be "brcm,ns2-pcie-phy" +- reg: MDIO Phy ID for the MDIO interface +- #phy-cells: must be 0 + +This is a child bus node of "brcm,mdio-mux-iproc" node. + +Example: + +mdio@0 { + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + pci_phy0: pci-phy@0 { + compatible = "brcm,ns2-pcie-phy"; + reg = <0x0>; + #phy-cells = <0>; + }; +}; -- cgit v1.3-14-g43fede From 3f3f67cbf64227fc9c06113585d9570baddc9bcd Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Mon, 9 May 2016 13:48:27 +0200 Subject: PCI: Add DT binding for Axis ARTPEC-6 PCIe controller Add the Device Tree binding documentation that allows to describe the PCIe controller found in the Axis ARTPEC-6 SoC. Signed-off-by: Niklas Cassel Signed-off-by: Bjorn Helgaas Acked-by: Rob Herring --- .../devicetree/bindings/pci/axis,artpec6-pcie.txt | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt new file mode 100644 index 000000000000..330a45b5f0b5 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt @@ -0,0 +1,46 @@ +* Axis ARTPEC-6 PCIe interface + +This PCIe host controller is based on the Synopsys DesignWare PCIe IP +and thus inherits all the common properties defined in designware-pcie.txt. + +Required properties: +- compatible: "axis,artpec6-pcie", "snps,dw-pcie" +- reg: base addresses and lengths of the PCIe controller (DBI), + the phy controller, and configuration address space. +- reg-names: Must include the following entries: + - "dbi" + - "phy" + - "config" +- interrupts: A list of interrupt outputs of the controller. Must contain an + entry for each entry in the interrupt-names property. +- interrupt-names: Must include the following entries: + - "msi": The interrupt that is asserted when an MSI is received +- axis,syscon-pcie: A phandle pointing to the ARTPEC-6 system controller, + used to enable and control the Synopsys IP. + +Example: + + pcie@f8050000 { + compatible = "axis,artpec6-pcie", "snps,dw-pcie"; + reg = <0xf8050000 0x2000 + 0xf8040000 0x1000 + 0xc0000000 0x1000>; + reg-names = "dbi", "phy", "config"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + /* downstream I/O */ + ranges = <0x81000000 0 0x00010000 0xc0010000 0 0x00010000 + /* non-prefetchable memory */ + 0x82000000 0 0xc0020000 0xc0020000 0 0x1ffe0000>; + num-lanes = <2>; + interrupts = ; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>; + axis,syscon-pcie = <&syscon>; + }; -- cgit v1.3-14-g43fede From ece85839d228d8b2948a69b6f9929266bb8d5901 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 3 Jun 2016 18:25:21 -0500 Subject: dt/bindings: firmware: Add Qualcomm SCM binding This patch adds the device tree support for the Qualcomm SCM firmware. Signed-off-by: Andy Gross Reviewed-by: Stephen Boyd Acked-by: Bjorn Andersson Acked-by: Rob Herring --- .../devicetree/bindings/firmware/qcom,scm.txt | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scm.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt new file mode 100644 index 000000000000..3b4436e56865 --- /dev/null +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt @@ -0,0 +1,28 @@ +QCOM Secure Channel Manager (SCM) + +Qualcomm processors include an interface to communicate to the secure firmware. +This interface allows for clients to request different types of actions. These +can include CPU power up/down, HDCP requests, loading of firmware, and other +assorted actions. + +Required properties: +- compatible: must contain one of the following: + * "qcom,scm-apq8064" for APQ8064 platforms + * "qcom,scm-msm8660" for MSM8660 platforms + * "qcom,scm-msm8690" for MSM8690 platforms + * "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc) +- clocks: One to three clocks may be required based on compatible. + * Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960" + * Core, iface, and bus clocks required for "qcom,scm" +- clock-names: Must contain "core" for the core clock, "iface" for the interface + clock and "bus" for the bus clock per the requirements of the compatible. + +Example for MSM8916: + + firmware { + scm { + compatible = "qcom,scm"; + clocks = <&gcc GCC_CRYPTO_CLK> , <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>; + clock-names = "core", "bus", "iface"; + }; + }; -- cgit v1.3-14-g43fede From c49e9e95f4d1f771e25cf6540503a4ab88798325 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 6 Jun 2016 16:58:19 -0700 Subject: dt: binding: Add Qualcomm WCNSS control binding This binding describes the control interface for the Qualcomm WCNSS. Signed-off-by: Bjorn Andersson Acked-by: Rob Herring Signed-off-by: Andy Gross --- .../devicetree/bindings/soc/qcom/qcom,wcnss.txt | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.txt new file mode 100644 index 000000000000..4ea39e9186a7 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.txt @@ -0,0 +1,116 @@ +Qualcomm WCNSS Binding + +This binding describes the Qualcomm WCNSS hardware. It consists of control +block and a BT, WiFi and FM radio block, all using SMD as command channels. + +- compatible: + Usage: required + Value type: + Definition: must be: "qcom,wcnss", + +- qcom,smd-channel: + Usage: required + Value type: + Definition: standard SMD property specifying the SMD channel used for + communication with the WiFi firmware. + Should be "WCNSS_CTRL". + +- qcom,mmio: + Usage: required + Value type: + Definition: reference to a node specifying the wcnss "ccu" and "dxe" + register blocks. The node must be compatible with one of + the following: + "qcom,riva", + "qcom,pronto" + += SUBNODES +The subnodes of the wcnss node are optional and describe the individual blocks in +the WCNSS. + +== Bluetooth +The following properties are defined to the bluetooth node: + +- compatible: + Usage: required + Value type: + Definition: must be: + "qcom,wcnss-bt" + +== WiFi +The following properties are defined to the WiFi node: + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,wcnss-wlan", + +- interrupts: + Usage: required + Value type: + Definition: should specify the "rx" and "tx" interrupts + +- interrupt-names: + Usage: required + Value type: + Definition: must contain "rx" and "tx" + +- qcom,smem-state: + Usage: required + Value type: + Definition: should reference the tx-enable and tx-rings-empty SMEM states + +- qcom,smem-state-names: + Usage: required + Value type: + Definition: must contain "tx-enable" and "tx-rings-empty" + += EXAMPLE +The following example represents a SMD node, with one edge representing the +"pronto" subsystem, with the wcnss device and its wcn3680 BT and WiFi blocks +described; as found on the 8974 platform. + +smd { + compatible = "qcom,smd"; + + pronto-edge { + interrupts = <0 142 1>; + + qcom,ipc = <&apcs 8 17>; + qcom,smd-edge = <6>; + + wcnss { + compatible = "qcom,wcnss"; + qcom,smd-channels = "WCNSS_CTRL"; + + #address-cells = <1>; + #size-cells = <1>; + + qcom,mmio = <&pronto>; + + bt { + compatible = "qcom,wcnss-bt"; + }; + + wlan { + compatible = "qcom,wcnss-wlan"; + + interrupts = <0 145 0>, <0 146 0>; + interrupt-names = "tx", "rx"; + + qcom,smem-state = <&apps_smsm 10>, <&apps_smsm 9>; + qcom,smem-state-names = "tx-enable", "tx-rings-empty"; + }; + }; + }; +}; + +soc { + pronto: pronto { + compatible = "qcom,pronto"; + + reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>; + reg-names = "ccu", "dxe", "pmu"; + }; +}; -- cgit v1.3-14-g43fede From 29380905565655bb797bf670a173bddb8e641da6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 3 Jun 2016 18:31:19 +0200 Subject: ARM: imx6: disable deeper idle states when FEC is active w/o HW workaround The i.MX6 Q/DL has an erratum (ERR006687) that prevents the FEC from waking the CPUs when they are in wait(unclocked) state. As the hardware workaround isn't applicable to all boards, disable the deeper idle state when the workaround isn't present and the FEC is in use. This allows to safely run a kernel with CPUidle enabled on all i.MX6 boards. Signed-off-by: Lucas Stach Acked-by: David S. Miller (for network changes) Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/net/fsl-fec.txt | 3 +++ arch/arm/mach-imx/cpuidle-imx6q.c | 16 +++++++++++++++ drivers/net/ethernet/freescale/fec.h | 2 ++ drivers/net/ethernet/freescale/fec_main.c | 12 +++++++++++ include/soc/imx/cpuidle.h | 25 +++++++++++++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 include/soc/imx/cpuidle.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt index b037a9d78d93..a1e3693cca16 100644 --- a/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -27,6 +27,9 @@ Optional properties: number to 1. - fsl,magic-packet : If present, indicates that the hardware supports waking up via magic packet. +- fsl,err006687-workaround-present: If present indicates that the system has + the hardware workaround for ERR006687 applied and does not need a software + workaround. Optional subnodes: - mdio : specifies the mdio bus in the FEC, used as a container for phy nodes diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index 353bb8774112..c3cc8ca8d2ff 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -62,6 +62,22 @@ static struct cpuidle_driver imx6q_cpuidle_driver = { .safe_state_index = 0, }; +/* + * i.MX6 Q/DL has an erratum (ERR006687) that prevents the FEC from waking the + * CPUs when they are in wait(unclocked) state. As the hardware workaround isn't + * applicable to all boards, disable the deeper idle state when the workaround + * isn't present and the FEC is in use. + */ +void imx6q_cpuidle_fec_irqs_used(void) +{ + imx6q_cpuidle_driver.states[1].disabled = true; +} + +void imx6q_cpuidle_fec_irqs_unused(void) +{ + imx6q_cpuidle_driver.states[1].disabled = false; +} + int __init imx6q_cpuidle_init(void) { /* Set INT_MEM_CLK_LPM bit to get a reliable WAIT mode support */ diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index f58f9ea51639..dc71a88e9c55 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -442,6 +442,8 @@ struct bufdesc_ex { #define FEC_QUIRK_SINGLE_MDIO (1 << 11) /* Controller supports RACC register */ #define FEC_QUIRK_HAS_RACC (1 << 12) +/* Interrupt doesn't wake CPU from deep idle */ +#define FEC_QUIRK_ERR006687 (1 << 13) struct bufdesc_prop { int qid; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ca2cccc594fd..8c2110b61684 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -60,6 +60,7 @@ #include #include #include +#include #include @@ -2820,6 +2821,9 @@ fec_enet_open(struct net_device *ndev) if (ret) goto err_enet_mii_probe; + if (fep->quirks & FEC_QUIRK_ERR006687) + imx6q_cpuidle_fec_irqs_used(); + napi_enable(&fep->napi); phy_start(ndev->phydev); netif_tx_start_all_queues(ndev); @@ -2855,6 +2859,9 @@ fec_enet_close(struct net_device *ndev) phy_disconnect(ndev->phydev); + if (fep->quirks & FEC_QUIRK_ERR006687) + imx6q_cpuidle_fec_irqs_unused(); + fec_enet_clk_enable(ndev, false); pinctrl_pm_select_sleep_state(&fep->pdev->dev); pm_runtime_mark_last_busy(&fep->pdev->dev); @@ -3294,6 +3301,11 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); + if ((of_machine_is_compatible("fsl,imx6q") || + of_machine_is_compatible("fsl,imx6dl")) && + !of_property_read_bool(np, "fsl,err006687-workaround-present")) + fep->quirks |= FEC_QUIRK_ERR006687; + if (of_get_property(np, "fsl,magic-packet", NULL)) fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET; diff --git a/include/soc/imx/cpuidle.h b/include/soc/imx/cpuidle.h new file mode 100644 index 000000000000..986a4823bce1 --- /dev/null +++ b/include/soc/imx/cpuidle.h @@ -0,0 +1,25 @@ +/* + * Copyright 2016 Pengutronix, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __SOC_IMX_CPUIDLE_H__ +#define __SOC_IMX_CPUIDLE_H__ + +#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_SOC_IMX6Q) +void imx6q_cpuidle_fec_irqs_used(void); +void imx6q_cpuidle_fec_irqs_unused(void); +#else +void imx6q_cpuidle_fec_irqs_used(void) { } +void imx6q_cpuidle_fec_irqs_unused(void) { } +#endif + +#endif /* __SOC_IMX_CPUIDLE_H__ */ -- cgit v1.3-14-g43fede From 3a0000f0cabba5e6e1d61e969250fc31e33f18bc Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Fri, 10 Jun 2016 16:46:33 +0930 Subject: gpio: Fix paths to GPIO driver source files Signed-off-by: Andrew Jeffery Signed-off-by: Linus Walleij --- Documentation/gpio/drivers-on-gpio.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpio/drivers-on-gpio.txt b/Documentation/gpio/drivers-on-gpio.txt index 14bf95a13bae..306513251713 100644 --- a/Documentation/gpio/drivers-on-gpio.txt +++ b/Documentation/gpio/drivers-on-gpio.txt @@ -37,15 +37,16 @@ hardware descriptions such as device tree or ACPI: external connector status, such as a headset line for an audio driver or an HDMI connector. It will provide a better userspace sysfs interface than GPIO. -- restart-gpio: drivers/power/gpio-restart.c is used to restart/reboot the - system by pulling a GPIO line and will register a restart handler so +- restart-gpio: drivers/power/reset/gpio-restart.c is used to restart/reboot + the system by pulling a GPIO line and will register a restart handler so userspace can issue the right system call to restart the system. -- poweroff-gpio: drivers/power/gpio-poweroff.c is used to power the system down - by pulling a GPIO line and will register a pm_power_off() callback so that - userspace can issue the right system call to power down the system. +- poweroff-gpio: drivers/power/reset/gpio-poweroff.c is used to power the + system down by pulling a GPIO line and will register a pm_power_off() + callback so that userspace can issue the right system call to power down the + system. -- gpio-gate-clock: drivers/clk/clk-gpio-gate.c is used to control a gated clock +- gpio-gate-clock: drivers/clk/clk-gpio.c is used to control a gated clock (off/on) that uses a GPIO, and integrated with the clock subsystem. - i2c-gpio: drivers/i2c/busses/i2c-gpio.c is used to drive an I2C bus -- cgit v1.3-14-g43fede From 191a79fff8ea88259d94714158cdf7a51c5bf6d3 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Fri, 10 Jun 2016 16:46:34 +0930 Subject: pinctrl: Fix grammar in pinmux request list Signed-off-by: Andrew Jeffery Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 4976389e432d..cefcf5d88a1c 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -493,12 +493,12 @@ Definitions: - The combination of a FUNCTION and a PIN GROUP determine a certain function for a certain set of pins. The knowledge of the functions and pin groups and their machine-specific particulars are kept inside the pinmux driver, - from the outside only the enumerators are known, and the driver core can: + from the outside only the enumerators are known, and the driver core can + request: - - Request the name of a function with a certain selector (>= 0) + - The name of a function with a certain selector (>= 0) - A list of groups associated with a certain function - - Request that a certain group in that list to be activated for a certain - function + - That a certain group in that list to be activated for a certain function As already described above, pin groups are in turn self-descriptive, so the core will retrieve the actual pin range in a certain group from the -- cgit v1.3-14-g43fede From eef06737e5dd9baa1ec8606f74356575ab15291d Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Fri, 10 Jun 2016 16:46:35 +0930 Subject: pinctrl: s/have/has/ in GPIO driver interaction description Signed-off-by: Andrew Jeffery Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index cefcf5d88a1c..07d102c3d05a 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -286,7 +286,7 @@ see the section named "pin control requests from drivers" and "drivers needing both pin control and GPIOs" below for details. But in some situations a cross-subsystem mapping between pins and GPIOs is needed. -Since the pin controller subsystem have its pinspace local to the pin +Since the pin controller subsystem has its pinspace local to the pin controller we need a mapping so that the pin control subsystem can figure out which pin controller handles control of a certain GPIO pin. Since a single pin controller may be muxing several GPIO ranges (typically SoCs that have -- cgit v1.3-14-g43fede From 73f8fed031d51868b57835cb1616c6aeea20a8d0 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Fri, 10 Jun 2016 16:46:36 +0930 Subject: pinctrl: Reflow/wrap paragraph describing GPIO interaction Signed-off-by: Andrew Jeffery Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 07d102c3d05a..6414a613cb8a 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -286,13 +286,13 @@ see the section named "pin control requests from drivers" and "drivers needing both pin control and GPIOs" below for details. But in some situations a cross-subsystem mapping between pins and GPIOs is needed. -Since the pin controller subsystem has its pinspace local to the pin -controller we need a mapping so that the pin control subsystem can figure out -which pin controller handles control of a certain GPIO pin. Since a single -pin controller may be muxing several GPIO ranges (typically SoCs that have -one set of pins, but internally several GPIO silicon blocks, each modelled as -a struct gpio_chip) any number of GPIO ranges can be added to a pin controller -instance like this: +Since the pin controller subsystem has its pinspace local to the pin controller +we need a mapping so that the pin control subsystem can figure out which pin +controller handles control of a certain GPIO pin. Since a single pin controller +may be muxing several GPIO ranges (typically SoCs that have one set of pins, +but internally several GPIO silicon blocks, each modelled as a struct +gpio_chip) any number of GPIO ranges can be added to a pin controller instance +like this: struct gpio_chip chip_a; struct gpio_chip chip_b; -- cgit v1.3-14-g43fede From 7cdeb24db4d12d42c237f28afade69c09e8a85e2 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 4 Jan 2016 18:36:37 +0100 Subject: dt-bindings: drm/mediatek: Add Mediatek HDMI dts binding Add the device tree binding documentation for Mediatek HDMI, HDMI PHY and HDMI DDC devices. Signed-off-by: Philipp Zabel Acked-by: Rob Herring --- .../bindings/display/mediatek/mediatek,hdmi.txt | 148 +++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt new file mode 100644 index 000000000000..7b124242b0c5 --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,hdmi.txt @@ -0,0 +1,148 @@ +Mediatek HDMI Encoder +===================== + +The Mediatek HDMI encoder can generate HDMI 1.4a or MHL 2.0 signals from +its parallel input. + +Required properties: +- compatible: Should be "mediatek,-hdmi". +- reg: Physical base address and length of the controller's registers +- interrupts: The interrupt signal from the function block. +- clocks: device clocks + See Documentation/devicetree/bindings/clock/clock-bindings.txt for details. +- clock-names: must contain "pixel", "pll", "bclk", and "spdif". +- phys: phandle link to the HDMI PHY node. + See Documentation/devicetree/bindings/phy/phy-bindings.txt for details. +- phy-names: must contain "hdmi" +- mediatek,syscon-hdmi: phandle link and register offset to the system + configuration registers. For mt8173 this must be offset 0x900 into the + MMSYS_CONFIG region: <&mmsys 0x900>. +- ports: A node containing input and output port nodes with endpoint + definitions as documented in Documentation/devicetree/bindings/graph.txt. +- port@0: The input port in the ports node should be connected to a DPI output + port. +- port@1: The output port in the ports node should be connected to the input + port of a connector node that contains a ddc-i2c-bus property, or to the + input port of an attached bridge chip, such as a SlimPort transmitter. + +HDMI CEC +======== + +The HDMI CEC controller handles hotplug detection and CEC communication. + +Required properties: +- compatible: Should be "mediatek,-cec" +- reg: Physical base address and length of the controller's registers +- interrupts: The interrupt signal from the function block. +- clocks: device clock + +HDMI DDC +======== + +The HDMI DDC i2c controller is used to interface with the HDMI DDC pins. +The Mediatek's I2C controller is used to interface with I2C devices. + +Required properties: +- compatible: Should be "mediatek,-hdmi-ddc" +- reg: Physical base address and length of the controller's registers +- clocks: device clock +- clock-names: Should be "ddc-i2c". + +HDMI PHY +======== + +The HDMI PHY serializes the HDMI encoder's three channel 10-bit parallel +output and drives the HDMI pads. + +Required properties: +- compatible: "mediatek,-hdmi-phy" +- reg: Physical base address and length of the module's registers +- clocks: PLL reference clock +- clock-names: must contain "pll_ref" +- clock-output-names: must be "hdmitx_dig_cts" on mt8173 +- #phy-cells: must be <0> +- #clock-cells: must be <0> + +Optional properties: +- mediatek,ibias: TX DRV bias current for <1.65Gbps, defaults to 0xa +- mediatek,ibias_up: TX DRV bias current for >1.65Gbps, defaults to 0x1c + +Example: + +cec: cec@10013000 { + compatible = "mediatek,mt8173-cec"; + reg = <0 0x10013000 0 0xbc>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_CEC>; +}; + +hdmi_phy: hdmi-phy@10209100 { + compatible = "mediatek,mt8173-hdmi-phy"; + reg = <0 0x10209100 0 0x24>; + clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; + clock-names = "pll_ref"; + clock-output-names = "hdmitx_dig_cts"; + mediatek,ibias = <0xa>; + mediatek,ibias_up = <0x1c>; + #clock-cells = <0>; + #phy-cells = <0>; +}; + +hdmi_ddc0: i2c@11012000 { + compatible = "mediatek,mt8173-hdmi-ddc"; + reg = <0 0x11012000 0 0x1c>; + interrupts = ; + clocks = <&pericfg CLK_PERI_I2C5>; + clock-names = "ddc-i2c"; +}; + +hdmi0: hdmi@14025000 { + compatible = "mediatek,mt8173-hdmi"; + reg = <0 0x14025000 0 0x400>; + interrupts = ; + clocks = <&mmsys CLK_MM_HDMI_PIXEL>, + <&mmsys CLK_MM_HDMI_PLLCK>, + <&mmsys CLK_MM_HDMI_AUDIO>, + <&mmsys CLK_MM_HDMI_SPDIF>; + clock-names = "pixel", "pll", "bclk", "spdif"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pin>; + phys = <&hdmi_phy>; + phy-names = "hdmi"; + mediatek,syscon-hdmi = <&mmsys 0x900>; + assigned-clocks = <&topckgen CLK_TOP_HDMI_SEL>; + assigned-clock-parents = <&hdmi_phy>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hdmi0_in: endpoint { + remote-endpoint = <&dpi0_out>; + }; + }; + + port@1 { + reg = <1>; + + hdmi0_out: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; + }; + }; +}; + +connector { + compatible = "hdmi-connector"; + type = "a"; + ddc-i2c-bus = <&hdmiddc0>; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi0_out>; + }; + }; +}; -- cgit v1.3-14-g43fede From 39f8f23d13666c4c5644e5add7d9598d9e798f22 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Tue, 7 Jun 2016 16:12:33 +0100 Subject: dt-bindings: arm-gic: Add documentation for Tegra210 AGIC The Tegra AGIC interrupt controller is compatible with the ARM GIC-400 interrupt controller. Add the compatible string and clock information for the AGIC to the GIC device-tree binding documentation. Signed-off-by: Jon Hunter Acked-by: Rob Herring Signed-off-by: Marc Zyngier --- Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt index 793c20ff8fcc..5393e2a45a42 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt @@ -21,6 +21,7 @@ Main node required properties: "arm,pl390" "arm,tc11mp-gic" "brcm,brahma-b15-gic" + "nvidia,tegra210-agic" "qcom,msm-8660-qgic" "qcom,msm-qgic2" - interrupt-controller : Identifies the node as an interrupt controller @@ -68,7 +69,7 @@ Optional "ic_clk" (for "arm,arm11mp-gic") "PERIPHCLKEN" (for "arm,cortex-a15-gic") "PERIPHCLK", "PERIPHCLKEN" (for "arm,cortex-a9-gic") - "clk" (for "arm,gic-400") + "clk" (for "arm,gic-400" and "nvidia,tegra210") "gclk" (for "arm,pl390") - power-domains : A phandle and PM domain specifier as defined by bindings of -- cgit v1.3-14-g43fede From 1b8b9c81a99ace2c706aa8696e12dd846df50078 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 8 Jun 2016 13:58:22 +0200 Subject: s390/Documentation: improve sort command for trace buffer When s390 traces with hex_ascii or sprintf view are extracted and sorted, use the sort option -s (stable) to avoid multiple lines with the same time stamp being sorted using the rest of the line as secondary key. Signed-off-by: Thomas Richter Signed-off-by: Martin Schwidefsky --- Documentation/s390/s390dbf.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt index 3da163383c93..61329fd62e89 100644 --- a/Documentation/s390/s390dbf.txt +++ b/Documentation/s390/s390dbf.txt @@ -405,7 +405,7 @@ Example: > ls /sys/kernel/debug/s390dbf/dasd flush hex_ascii level pages raw -> cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort +1 +> cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort -k2,2 -s 00 00974733272:680099 2 - 02 0006ad7e 07 ea 4a 90 | .... 00 00974733272:682210 2 - 02 0006ade6 46 52 45 45 | FREE 00 00974733272:682213 2 - 02 0006adf6 07 ea 4a 90 | .... -- cgit v1.3-14-g43fede From a62247e1f5c13b926f535bb64ecbd7f9fdef7b21 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 21 May 2016 11:10:13 +0200 Subject: topology/sysfs: provide drawer id and siblings attributes The s390 cpu topology gained another hierarchy level. The top level is now called drawer and contains several books. A book used to be the top level. In order to expose the cpu topology to user space allow to create new sysfs attributes dependent on CONFIG_SCHED_DRAWER which an architecture may define and select. These additional attributes will be available: /sys/devices/system/cpu/cpuX/topology/drawer_id /sys/devices/system/cpu/cpuX/topology/drawer_siblings /sys/devices/system/cpu/cpuX/topology/drawer_siblings_list Signed-off-by: Heiko Carstens Acked-by: Peter Zijlstra (Intel) Signed-off-by: Martin Schwidefsky --- Documentation/cputopology.txt | 40 ++++++++++++++++++++++++++++++++-------- drivers/base/topology.c | 13 +++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt index 12b1b25b4da9..f722f227a73b 100644 --- a/Documentation/cputopology.txt +++ b/Documentation/cputopology.txt @@ -20,48 +20,70 @@ to /proc/cpuinfo output of some architectures: identifier (rather than the kernel's). The actual value is architecture and platform dependent. -4) /sys/devices/system/cpu/cpuX/topology/thread_siblings: +4) /sys/devices/system/cpu/cpuX/topology/drawer_id: + + the drawer ID of cpuX. Typically it is the hardware platform's + identifier (rather than the kernel's). The actual value is + architecture and platform dependent. + +5) /sys/devices/system/cpu/cpuX/topology/thread_siblings: internal kernel map of cpuX's hardware threads within the same core as cpuX. -5) /sys/devices/system/cpu/cpuX/topology/thread_siblings_list: +6) /sys/devices/system/cpu/cpuX/topology/thread_siblings_list: human-readable list of cpuX's hardware threads within the same core as cpuX. -6) /sys/devices/system/cpu/cpuX/topology/core_siblings: +7) /sys/devices/system/cpu/cpuX/topology/core_siblings: internal kernel map of cpuX's hardware threads within the same physical_package_id. -7) /sys/devices/system/cpu/cpuX/topology/core_siblings_list: +8) /sys/devices/system/cpu/cpuX/topology/core_siblings_list: human-readable list of cpuX's hardware threads within the same physical_package_id. -8) /sys/devices/system/cpu/cpuX/topology/book_siblings: +9) /sys/devices/system/cpu/cpuX/topology/book_siblings: internal kernel map of cpuX's hardware threads within the same book_id. -9) /sys/devices/system/cpu/cpuX/topology/book_siblings_list: +10) /sys/devices/system/cpu/cpuX/topology/book_siblings_list: human-readable list of cpuX's hardware threads within the same book_id. +11) /sys/devices/system/cpu/cpuX/topology/drawer_siblings: + + internal kernel map of cpuX's hardware threads within the same + drawer_id. + +12) /sys/devices/system/cpu/cpuX/topology/drawer_siblings_list: + + human-readable list of cpuX's hardware threads within the same + drawer_id. + To implement it in an architecture-neutral way, a new source file, -drivers/base/topology.c, is to export the 6 or 9 attributes. The three book -related sysfs files will only be created if CONFIG_SCHED_BOOK is selected. +drivers/base/topology.c, is to export the 6 to 12 attributes. The book +and drawer related sysfs files will only be created if CONFIG_SCHED_BOOK +and CONFIG_SCHED_DRAWER are selected. + +CONFIG_SCHED_BOOK and CONFIG_DRAWER are currently only used on s390, where +they reflect the cpu and cache hierarchy. For an architecture to support this feature, it must define some of these macros in include/asm-XXX/topology.h: #define topology_physical_package_id(cpu) #define topology_core_id(cpu) #define topology_book_id(cpu) +#define topology_drawer_id(cpu) #define topology_sibling_cpumask(cpu) #define topology_core_cpumask(cpu) #define topology_book_cpumask(cpu) +#define topology_drawer_cpumask(cpu) The type of **_id macros is int. The type of **_cpumask macros is (const) struct cpumask *. The latter @@ -78,6 +100,8 @@ not defined by include/asm-XXX/topology.h: For architectures that don't support books (CONFIG_SCHED_BOOK) there are no default definitions for topology_book_id() and topology_book_cpumask(). +For architectures that don't support drawes (CONFIG_SCHED_DRAWER) there are +no default definitions for topology_drawer_id() and topology_drawer_cpumask(). Additionally, CPU topology information is provided under /sys/devices/system/cpu and includes these files. The internal diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 8b7d7f8e5851..df3c97cb4c99 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -77,6 +77,14 @@ static DEVICE_ATTR_RO(book_siblings); static DEVICE_ATTR_RO(book_siblings_list); #endif +#ifdef CONFIG_SCHED_DRAWER +define_id_show_func(drawer_id); +static DEVICE_ATTR_RO(drawer_id); +define_siblings_show_func(drawer_siblings, drawer_cpumask); +static DEVICE_ATTR_RO(drawer_siblings); +static DEVICE_ATTR_RO(drawer_siblings_list); +#endif + static struct attribute *default_attrs[] = { &dev_attr_physical_package_id.attr, &dev_attr_core_id.attr, @@ -88,6 +96,11 @@ static struct attribute *default_attrs[] = { &dev_attr_book_id.attr, &dev_attr_book_siblings.attr, &dev_attr_book_siblings_list.attr, +#endif +#ifdef CONFIG_SCHED_DRAWER + &dev_attr_drawer_id.attr, + &dev_attr_drawer_siblings.attr, + &dev_attr_drawer_siblings_list.attr, #endif NULL }; -- cgit v1.3-14-g43fede From 5aa1418defb0e88fb7f70c5b112d531cfcede851 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Thu, 9 Jun 2016 12:47:06 +0100 Subject: ASoC: dwc: Add irq parameter to DOCUMENTATION A parameter description for the interruptions of the I2S controller was added. Signed-off-by: Jose Abreu Acked-by: Rob Herring Cc: Carlos Palminha Cc: Mark Brown Cc: Liam Girdwood Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Rob Herring Cc: Alexey Brodkin Cc: linux-snps-arc@lists.infradead.org Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/designware-i2s.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/designware-i2s.txt b/Documentation/devicetree/bindings/sound/designware-i2s.txt index 7bb54247f8e8..6a536d570e29 100644 --- a/Documentation/devicetree/bindings/sound/designware-i2s.txt +++ b/Documentation/devicetree/bindings/sound/designware-i2s.txt @@ -12,6 +12,10 @@ Required properties: one for receive. - dma-names : "tx" for the transmit channel, "rx" for the receive channel. +Optional properties: + - interrupts: The interrupt line number for the I2S controller. Add this + parameter if the I2S controller that you are using does not support DMA. + For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties please check: * resource-names.txt -- cgit v1.3-14-g43fede From 36abef4e796d382e81a0c2d21ea5327481dd7154 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 3 Jun 2016 19:29:38 -0700 Subject: f2fs: introduce mode=lfs mount option This mount option is to enable original log-structured filesystem forcefully. So, there should be no random writes for main area. Especially, this supports host-managed SMR device. Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.txt | 3 +++ fs/f2fs/checkpoint.c | 2 +- fs/f2fs/data.c | 2 ++ fs/f2fs/f2fs.h | 2 ++ fs/f2fs/file.c | 8 +++++++- fs/f2fs/recovery.c | 6 +++++- fs/f2fs/segment.c | 20 +++++++++++++++++++- fs/f2fs/segment.h | 7 +++++++ fs/f2fs/super.c | 28 ++++++++++++++++++++++++++++ 9 files changed, 74 insertions(+), 4 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index e1c9f0849da6..3a5ce24021d9 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -151,6 +151,9 @@ noinline_data Disable the inline data feature, inline data feature is enabled by default. data_flush Enable data flushing before checkpoint in order to persist data of regular and symlink. +mode=%s Control block allocation mode which supports "adaptive" + and "lfs". In "lfs" mode, there should be no random + writes towards main area. ================================================================================ DEBUGFS ENTRIES diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 4179c7b971fc..837e6bcad5ce 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -981,7 +981,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) * This avoids to conduct wrong roll-forward operations and uses * metapages, so should be called prior to sync_meta_pages below. */ - if (discard_next_dnode(sbi, discard_blk)) + if (!test_opt(sbi, LFS) && discard_next_dnode(sbi, discard_blk)) invalidate = true; /* Flush all the NAT/SIT pages */ diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 5f655d0c5b1f..607ef4397330 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1710,6 +1710,8 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) return 0; + if (test_opt(F2FS_I_SB(inode), LFS)) + return 0; trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 24c7cde84905..82acdec022ef 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -111,6 +111,8 @@ static inline bool time_to_inject(int type) #define F2FS_MOUNT_FORCE_FG_GC 0x00004000 #define F2FS_MOUNT_DATA_FLUSH 0x00008000 #define F2FS_MOUNT_FAULT_INJECTION 0x00010000 +#define F2FS_MOUNT_ADAPTIVE 0x00020000 +#define F2FS_MOUNT_LFS 0x00040000 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option) #define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7a8d262bc488..b9d745ef5b08 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -878,9 +878,15 @@ static int __exchange_data_block(struct inode *inode, pgoff_t src, return full ? truncate_hole(inode, dst, dst + 1) : 0; if (do_replace) { - struct page *ipage = get_node_page(sbi, inode->i_ino); + struct page *ipage; struct node_info ni; + if (test_opt(sbi, LFS)) { + ret = -ENOTSUPP; + goto err_out; + } + + ipage = get_node_page(sbi, inode->i_ino); if (IS_ERR(ipage)) { ret = PTR_ERR(ipage); goto err_out; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index b568b28c74f2..a39d84ab66b2 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -624,8 +624,12 @@ out: if (err) { bool invalidate = false; - if (discard_next_dnode(sbi, blkaddr)) + if (test_opt(sbi, LFS)) { + update_meta_page(sbi, NULL, blkaddr); invalidate = true; + } else if (discard_next_dnode(sbi, blkaddr)) { + invalidate = true; + } /* Flush all the NAT/SIT pages */ while (get_pages(sbi, F2FS_DIRTY_META)) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index eff046a792ad..4792f94089f7 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -707,6 +707,7 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc) struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); unsigned long *prefree_map = dirty_i->dirty_segmap[PRE]; unsigned int start = 0, end = -1; + unsigned int secno, start_segno; mutex_lock(&dirty_i->seglist_lock); @@ -726,8 +727,22 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc) if (!test_opt(sbi, DISCARD)) continue; - f2fs_issue_discard(sbi, START_BLOCK(sbi, start), + if (!test_opt(sbi, LFS) || sbi->segs_per_sec == 1) { + f2fs_issue_discard(sbi, START_BLOCK(sbi, start), (end - start) << sbi->log_blocks_per_seg); + continue; + } +next: + secno = GET_SECNO(sbi, start); + start_segno = secno * sbi->segs_per_sec; + if (!IS_CURSEC(sbi, secno) && + !get_valid_blocks(sbi, start, sbi->segs_per_sec)) + f2fs_issue_discard(sbi, START_BLOCK(sbi, start_segno), + sbi->segs_per_sec << sbi->log_blocks_per_seg); + + start = start_segno + sbi->segs_per_sec; + if (start < end) + goto next; } mutex_unlock(&dirty_i->seglist_lock); @@ -1221,6 +1236,9 @@ void allocate_new_segments(struct f2fs_sb_info *sbi) { int i; + if (test_opt(sbi, LFS)) + return; + for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) __allocate_new_segments(sbi, i); } diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 890bb28d2082..d74cc330ae13 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -470,6 +470,10 @@ static inline bool need_SSR(struct f2fs_sb_info *sbi) { int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); + + if (test_opt(sbi, LFS)) + return false; + return free_sections(sbi) <= (node_secs + 2 * dent_secs + reserved_sections(sbi) + 1); } @@ -533,6 +537,9 @@ static inline bool need_inplace_update(struct inode *inode) if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode)) return false; + if (test_opt(sbi, LFS)) + return false; + if (policy & (0x1 << F2FS_IPU_FORCE)) return true; if (policy & (0x1 << F2FS_IPU_SSR) && need_SSR(sbi)) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index dc66f1623e06..edc736de8ee9 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -94,6 +94,7 @@ enum { Opt_noextent_cache, Opt_noinline_data, Opt_data_flush, + Opt_mode, Opt_fault_injection, Opt_lazytime, Opt_nolazytime, @@ -123,6 +124,7 @@ static match_table_t f2fs_tokens = { {Opt_noextent_cache, "noextent_cache"}, {Opt_noinline_data, "noinline_data"}, {Opt_data_flush, "data_flush"}, + {Opt_mode, "mode=%s"}, {Opt_fault_injection, "fault_injection=%u"}, {Opt_lazytime, "lazytime"}, {Opt_nolazytime, "nolazytime"}, @@ -506,6 +508,25 @@ static int parse_options(struct super_block *sb, char *options) case Opt_data_flush: set_opt(sbi, DATA_FLUSH); break; + case Opt_mode: + name = match_strdup(&args[0]); + + if (!name) + return -ENOMEM; + if (strlen(name) == 8 && + !strncmp(name, "adaptive", 8)) { + set_opt(sbi, ADAPTIVE); + clear_opt(sbi, LFS); + } else if (strlen(name) == 3 && + !strncmp(name, "lfs", 3)) { + clear_opt(sbi, ADAPTIVE); + set_opt(sbi, LFS); + } else { + kfree(name); + return -EINVAL; + } + kfree(name); + break; case Opt_fault_injection: if (args->from && match_int(args, &arg)) return -EINVAL; @@ -870,6 +891,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) seq_puts(seq, ",noextent_cache"); if (test_opt(sbi, DATA_FLUSH)) seq_puts(seq, ",data_flush"); + + seq_puts(seq, ",mode="); + if (test_opt(sbi, ADAPTIVE)) + seq_puts(seq, "adaptive"); + else if (test_opt(sbi, LFS)) + seq_puts(seq, "lfs"); seq_printf(seq, ",active_logs=%u", sbi->active_logs); return 0; @@ -953,6 +980,7 @@ static void default_options(struct f2fs_sb_info *sbi) set_opt(sbi, EXTENT_CACHE); sbi->sb->s_flags |= MS_LAZYTIME; set_opt(sbi, FLUSH_MERGE); + set_opt(sbi, ADAPTIVE); #ifdef CONFIG_F2FS_FS_XATTR set_opt(sbi, XATTR_USER); -- cgit v1.3-14-g43fede From 9d26d3a8f1b0c442339a235f9508bdad8af91043 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 2 Jun 2016 11:17:12 +0300 Subject: PCI: Put PCIe ports into D3 during suspend Currently the Linux PCI core does not touch power state of PCI bridges and PCIe ports when system suspend is entered. Leaving them in D0 consumes power unnecessarily and may prevent the CPU from entering deeper C-states. With recent PCIe hardware we can power down the ports to save power given that we take into account few restrictions: - The PCIe port hardware is recent enough, starting from 2015. - Devices connected to PCIe ports are effectively in D3cold once the port is transitioned to D3 (the config space is not accessible anymore and the link may be powered down). - Devices behind the PCIe port need to be allowed to transition to D3cold and back. There is a way both drivers and userspace can forbid this. - If the device behind the PCIe port is capable of waking the system it needs to be able to do so from D3cold. This patch adds a new flag to struct pci_device called 'bridge_d3'. This flag is set and cleared by the PCI core whenever there is a change in power management state of any of the devices behind the PCIe port. When system later on is suspended we only need to check this flag and if it is true transition the port to D3 otherwise we leave it in D0. Also provide override mechanism via command line parameter "pcie_port_pm=[off|force]" that can be used to disable or enable the feature regardless of the BIOS manufacturing date. Tested-by: Lukas Wunner Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- Documentation/kernel-parameters.txt | 4 + drivers/pci/bus.c | 1 + drivers/pci/pci-driver.c | 5 +- drivers/pci/pci-sysfs.c | 5 ++ drivers/pci/pci.c | 175 ++++++++++++++++++++++++++++++++++++ drivers/pci/pci.h | 11 +++ drivers/pci/remove.c | 2 + drivers/usb/host/xhci-pci.c | 2 +- include/linux/pci.h | 3 + 9 files changed, 203 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..86edee4cedd4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3047,6 +3047,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe ports driver. + pcie_port_pm= [PCIE] PCIe port power management handling: + off Disable power management of all PCIe ports + force Forcibly enable power management of all PCIe ports + pcie_pme= [PCIE,PM] Native PCIe PME signaling options: nomsi Do not use MSI for native PCIe PME signaling (this makes all PCIe root ports use INTx for all services). diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index dd7cdbee8029..28731360b457 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -291,6 +291,7 @@ void pci_bus_add_device(struct pci_dev *dev) pci_fixup_device(pci_fixup_final, dev); pci_create_sysfs_dev_files(dev); pci_proc_attach_device(dev); + pci_bridge_d3_device_changed(dev); dev->match_driver = true; retval = device_attach(&dev->dev); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d7ffd66814bb..e39a67c8ef39 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -777,7 +777,7 @@ static int pci_pm_suspend_noirq(struct device *dev) if (!pci_dev->state_saved) { pci_save_state(pci_dev); - if (!pci_has_subordinate(pci_dev)) + if (pci_power_manageable(pci_dev)) pci_prepare_to_sleep(pci_dev); } @@ -1144,7 +1144,6 @@ static int pci_pm_runtime_suspend(struct device *dev) return -ENOSYS; pci_dev->state_saved = false; - pci_dev->no_d3cold = false; error = pm->runtime_suspend(dev); if (error) { /* @@ -1161,8 +1160,6 @@ static int pci_pm_runtime_suspend(struct device *dev) return error; } - if (!pci_dev->d3cold_allowed) - pci_dev->no_d3cold = true; pci_fixup_device(pci_fixup_suspend, pci_dev); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index d319a9ca9b7b..bcd10c795284 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -406,6 +406,11 @@ static ssize_t d3cold_allowed_store(struct device *dev, return -EINVAL; pdev->d3cold_allowed = !!val; + if (pdev->d3cold_allowed) + pci_d3cold_enable(pdev); + else + pci_d3cold_disable(pdev); + pm_runtime_resume(dev); return count; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c8b4dbdd1bdd..9ff7183e25a2 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -101,6 +102,21 @@ unsigned int pcibios_max_latency = 255; /* If set, the PCIe ARI capability will not be used. */ static bool pcie_ari_disabled; +/* Disable bridge_d3 for all PCIe ports */ +static bool pci_bridge_d3_disable; +/* Force bridge_d3 for all PCIe ports */ +static bool pci_bridge_d3_force; + +static int __init pcie_port_pm_setup(char *str) +{ + if (!strcmp(str, "off")) + pci_bridge_d3_disable = true; + else if (!strcmp(str, "force")) + pci_bridge_d3_force = true; + return 1; +} +__setup("pcie_port_pm=", pcie_port_pm_setup); + /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children * @bus: pointer to PCI bus structure to search @@ -2155,6 +2171,164 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) pm_runtime_put_sync(parent); } +/** + * pci_bridge_d3_possible - Is it possible to put the bridge into D3 + * @bridge: Bridge to check + * + * This function checks if it is possible to move the bridge to D3. + * Currently we only allow D3 for recent enough PCIe ports. + */ +static bool pci_bridge_d3_possible(struct pci_dev *bridge) +{ + unsigned int year; + + if (!pci_is_pcie(bridge)) + return false; + + switch (pci_pcie_type(bridge)) { + case PCI_EXP_TYPE_ROOT_PORT: + case PCI_EXP_TYPE_UPSTREAM: + case PCI_EXP_TYPE_DOWNSTREAM: + if (pci_bridge_d3_disable) + return false; + if (pci_bridge_d3_force) + return true; + + /* + * It should be safe to put PCIe ports from 2015 or newer + * to D3. + */ + if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && + year >= 2015) { + return true; + } + break; + } + + return false; +} + +static int pci_dev_check_d3cold(struct pci_dev *dev, void *data) +{ + bool *d3cold_ok = data; + bool no_d3cold; + + /* + * The device needs to be allowed to go D3cold and if it is wake + * capable to do so from D3cold. + */ + no_d3cold = dev->no_d3cold || !dev->d3cold_allowed || + (device_may_wakeup(&dev->dev) && !pci_pme_capable(dev, PCI_D3cold)) || + !pci_power_manageable(dev); + + *d3cold_ok = !no_d3cold; + + return no_d3cold; +} + +/* + * pci_bridge_d3_update - Update bridge D3 capabilities + * @dev: PCI device which is changed + * @remove: Is the device being removed + * + * Update upstream bridge PM capabilities accordingly depending on if the + * device PM configuration was changed or the device is being removed. The + * change is also propagated upstream. + */ +static void pci_bridge_d3_update(struct pci_dev *dev, bool remove) +{ + struct pci_dev *bridge; + bool d3cold_ok = true; + + bridge = pci_upstream_bridge(dev); + if (!bridge || !pci_bridge_d3_possible(bridge)) + return; + + pci_dev_get(bridge); + /* + * If the device is removed we do not care about its D3cold + * capabilities. + */ + if (!remove) + pci_dev_check_d3cold(dev, &d3cold_ok); + + if (d3cold_ok) { + /* + * We need to go through all children to find out if all of + * them can still go to D3cold. + */ + pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold, + &d3cold_ok); + } + + if (bridge->bridge_d3 != d3cold_ok) { + bridge->bridge_d3 = d3cold_ok; + /* Propagate change to upstream bridges */ + pci_bridge_d3_update(bridge, false); + } + + pci_dev_put(bridge); +} + +/** + * pci_bridge_d3_device_changed - Update bridge D3 capabilities on change + * @dev: PCI device that was changed + * + * If a device is added or its PM configuration, such as is it allowed to + * enter D3cold, is changed this function updates upstream bridge PM + * capabilities accordingly. + */ +void pci_bridge_d3_device_changed(struct pci_dev *dev) +{ + pci_bridge_d3_update(dev, false); +} + +/** + * pci_bridge_d3_device_removed - Update bridge D3 capabilities on remove + * @dev: PCI device being removed + * + * Function updates upstream bridge PM capabilities based on other devices + * still left on the bus. + */ +void pci_bridge_d3_device_removed(struct pci_dev *dev) +{ + pci_bridge_d3_update(dev, true); +} + +/** + * pci_d3cold_enable - Enable D3cold for device + * @dev: PCI device to handle + * + * This function can be used in drivers to enable D3cold from the device + * they handle. It also updates upstream PCI bridge PM capabilities + * accordingly. + */ +void pci_d3cold_enable(struct pci_dev *dev) +{ + if (dev->no_d3cold) { + dev->no_d3cold = false; + pci_bridge_d3_device_changed(dev); + } +} +EXPORT_SYMBOL_GPL(pci_d3cold_enable); + +/** + * pci_d3cold_disable - Disable D3cold for device + * @dev: PCI device to handle + * + * This function can be used in drivers to disable D3cold from the device + * they handle. It also updates upstream PCI bridge PM capabilities + * accordingly. + */ +void pci_d3cold_disable(struct pci_dev *dev) +{ + if (!dev->no_d3cold) { + dev->no_d3cold = true; + pci_bridge_d3_device_changed(dev); + } +} +EXPORT_SYMBOL_GPL(pci_d3cold_disable); + /** * pci_pm_init - Initialize PM functions of given PCI device * @dev: PCI device to handle. @@ -2189,6 +2363,7 @@ void pci_pm_init(struct pci_dev *dev) dev->pm_cap = pm; dev->d3_delay = PCI_PM_D3_WAIT; dev->d3cold_delay = PCI_PM_D3COLD_WAIT; + dev->bridge_d3 = pci_bridge_d3_possible(dev); dev->d3cold_allowed = true; dev->d1_support = false; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index a814bbb80fcb..9730c474b016 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -82,6 +82,8 @@ void pci_pm_init(struct pci_dev *dev); void pci_ea_init(struct pci_dev *dev); void pci_allocate_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev); +void pci_bridge_d3_device_changed(struct pci_dev *dev); +void pci_bridge_d3_device_removed(struct pci_dev *dev); static inline void pci_wakeup_event(struct pci_dev *dev) { @@ -94,6 +96,15 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev) return !!(pci_dev->subordinate); } +static inline bool pci_power_manageable(struct pci_dev *pci_dev) +{ + /* + * Currently we allow normal PCI devices and PCI bridges transition + * into D3 if their bridge_d3 is set. + */ + return !pci_has_subordinate(pci_dev) || pci_dev->bridge_d3; +} + struct pci_vpd_ops { ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 8982026637d5..d1ef7acf6930 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -96,6 +96,8 @@ static void pci_remove_bus_device(struct pci_dev *dev) dev->subordinate = NULL; } + pci_bridge_d3_device_removed(dev); + pci_destroy_dev(dev); } diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 48672fac7ff3..ac352fe391f4 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -382,7 +382,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) * need to have the registers polled during D3, so avoid D3cold. */ if (xhci->quirks & XHCI_COMP_MODE_QUIRK) - pdev->no_d3cold = true; + pci_d3cold_disable(pdev); if (xhci->quirks & XHCI_PME_STUCK_QUIRK) xhci_pme_quirk(hcd); diff --git a/include/linux/pci.h b/include/linux/pci.h index 8d748345b158..8597b423cb63 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -294,6 +294,7 @@ struct pci_dev { unsigned int d2_support:1; /* Low power state D2 is supported */ unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ unsigned int no_d3cold:1; /* D3cold is forbidden */ + unsigned int bridge_d3:1; /* Allow D3 for bridge */ unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ unsigned int mmio_always_on:1; /* disallow turning off io/mem decoding during bar sizing */ @@ -1083,6 +1084,8 @@ int pci_back_from_sleep(struct pci_dev *dev); bool pci_dev_run_wake(struct pci_dev *dev); bool pci_check_pme_status(struct pci_dev *dev); void pci_pme_wakeup_bus(struct pci_bus *bus); +void pci_d3cold_enable(struct pci_dev *dev); +void pci_d3cold_disable(struct pci_dev *dev); static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) -- cgit v1.3-14-g43fede From 0f614d834bccd3537881c5d0933803b407ce3283 Mon Sep 17 00:00:00 2001 From: Jean-Michel Hautbois Date: Sun, 31 Jan 2016 16:33:00 +0100 Subject: i2c: Add generic support passing secondary devices addresses Some I2C devices have multiple addresses assigned, for example each address corresponding to a different internal register map page of the device. So far drivers which need support for this have handled this with a driver specific and non-generic implementation, e.g. passing the additional address via platform data. This patch provides a new helper function called i2c_new_secondary_device() which is intended to provide a generic way to get the secondary address as well as instantiate a struct i2c_client for the secondary address. The function expects a pointer to the primary i2c_client, a name for the secondary address and an optional default address. The name is used as a handle to specify which secondary address to get. The default address is used as a fallback in case no secondary address was explicitly specified. In case no secondary address and no default address were specified the function returns NULL. For now the function only supports look-up of the secondary address from devicetree, but it can be extended in the future to for example support board files and/or ACPI. Signed-off-by: Jean-Michel Hautbois Acked-by: Rob Herring Acked-by: Mika Westerberg Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c.txt | 7 +++++ drivers/i2c/i2c-core.c | 41 +++++++++++++++++++++++++++ include/linux/i2c.h | 5 ++++ 3 files changed, 53 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt index c8d977ed847f..f31b2ad1552b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c.txt +++ b/Documentation/devicetree/bindings/i2c/i2c.txt @@ -62,6 +62,13 @@ wants to support one of the below features, it should adapt the bindings below. - wakeup-source device can be used as a wakeup source. +- reg + I2C slave addresses + +- reg-names + Names of map programmable addresses. + It can contain any map needing another address than default one. + Binding may contain optional "interrupts" property, describing interrupts used by the device. I2C core will assign "irq" interrupt (or the very first interrupt if not using interrupt names) as primary interrupt for the slave. diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index af11b658984d..952d2f0c02c5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1145,6 +1145,47 @@ struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) } EXPORT_SYMBOL_GPL(i2c_new_dummy); +/** + * i2c_new_secondary_device - Helper to get the instantiated secondary address + * and create the associated device + * @client: Handle to the primary client + * @name: Handle to specify which secondary address to get + * @default_addr: Used as a fallback if no secondary address was specified + * Context: can sleep + * + * I2C clients can be composed of multiple I2C slaves bound together in a single + * component. The I2C client driver then binds to the master I2C slave and needs + * to create I2C dummy clients to communicate with all the other slaves. + * + * This function creates and returns an I2C dummy client whose I2C address is + * retrieved from the platform firmware based on the given slave name. If no + * address is specified by the firmware default_addr is used. + * + * On DT-based platforms the address is retrieved from the "reg" property entry + * cell whose "reg-names" value matches the slave name. + * + * This returns the new i2c client, which should be saved for later use with + * i2c_unregister_device(); or NULL to indicate an error. + */ +struct i2c_client *i2c_new_secondary_device(struct i2c_client *client, + const char *name, + u16 default_addr) +{ + struct device_node *np = client->dev.of_node; + u32 addr = default_addr; + int i; + + if (np) { + i = of_property_match_string(np, "reg-names", name); + if (i >= 0) + of_property_read_u32_index(np, "reg", i, &addr); + } + + dev_dbg(&client->adapter->dev, "Address for %s : 0x%x\n", name, addr); + return i2c_new_dummy(client->adapter, addr); +} +EXPORT_SYMBOL_GPL(i2c_new_secondary_device); + /* ------------------------------------------------------------------------- */ /* I2C bus adapters -- one roots each I2C or SMBUS segment */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 96a25ae14494..6df7bad8c26c 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -349,6 +349,11 @@ extern int i2c_probe_func_quick_read(struct i2c_adapter *, unsigned short addr); extern struct i2c_client * i2c_new_dummy(struct i2c_adapter *adap, u16 address); +extern struct i2c_client * +i2c_new_secondary_device(struct i2c_client *client, + const char *name, + u16 default_addr); + extern void i2c_unregister_device(struct i2c_client *); #endif /* I2C */ -- cgit v1.3-14-g43fede From 027dfac694fc27ef0273afb810d9b1f9da57d6e1 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 1 Jun 2016 16:34:37 +1000 Subject: powerpc: Various typo fixes Signed-off-by: Andrea Gelmini Signed-off-by: Michael Ellerman --- Documentation/devicetree/bindings/rtc/rtc-opal.txt | 2 +- arch/powerpc/crypto/aes-spe-regs.h | 2 +- arch/powerpc/include/asm/book3s/64/mmu-hash.h | 2 +- arch/powerpc/include/asm/eeh.h | 2 +- arch/powerpc/include/asm/nohash/32/pte-44x.h | 2 +- arch/powerpc/include/asm/opal-api.h | 4 ++-- arch/powerpc/include/asm/pmac_feature.h | 2 +- arch/powerpc/include/asm/processor.h | 2 +- arch/powerpc/include/asm/ps3av.h | 2 +- arch/powerpc/include/asm/pte-common.h | 2 +- arch/powerpc/include/asm/smu.h | 2 +- arch/powerpc/include/asm/tsi108.h | 2 +- arch/powerpc/kernel/cpu_setup_6xx.S | 2 +- arch/powerpc/kernel/eeh_driver.c | 2 +- arch/powerpc/kernel/exceptions-64e.S | 2 +- arch/powerpc/kernel/pci_64.c | 2 +- arch/powerpc/kernel/process.c | 2 +- arch/powerpc/kernel/rtas-proc.c | 2 +- arch/powerpc/lib/rheap.c | 2 +- arch/powerpc/mm/hash_native_64.c | 4 ++-- arch/powerpc/oprofile/cell/spu_task_sync.c | 2 +- arch/powerpc/perf/core-book3s.c | 2 +- arch/powerpc/perf/hv-24x7.c | 2 +- arch/powerpc/perf/hv-24x7.h | 2 +- arch/powerpc/platforms/512x/clock-commonclk.c | 2 +- arch/powerpc/platforms/cell/iommu.c | 4 ++-- arch/powerpc/platforms/cell/spider-pic.c | 2 +- arch/powerpc/platforms/cell/spu_base.c | 4 ++-- arch/powerpc/platforms/cell/spufs/file.c | 2 +- arch/powerpc/platforms/cell/spufs/run.c | 2 +- arch/powerpc/platforms/cell/spufs/sched.c | 2 +- arch/powerpc/platforms/powermac/low_i2c.c | 2 +- arch/powerpc/platforms/powernv/pci-ioda.c | 2 +- arch/powerpc/platforms/pseries/eeh_pseries.c | 2 +- arch/powerpc/platforms/pseries/io_event_irq.c | 2 +- arch/powerpc/platforms/pseries/setup.c | 2 +- 36 files changed, 40 insertions(+), 40 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rtc/rtc-opal.txt b/Documentation/devicetree/bindings/rtc/rtc-opal.txt index a1734e5cb75b..2340938cd0f5 100644 --- a/Documentation/devicetree/bindings/rtc/rtc-opal.txt +++ b/Documentation/devicetree/bindings/rtc/rtc-opal.txt @@ -2,7 +2,7 @@ IBM OPAL real-time clock ------------------------ Required properties: -- comapatible: Should be "ibm,opal-rtc" +- compatible: Should be "ibm,opal-rtc" Optional properties: - wakeup-source: Decides if the wakeup is supported or not diff --git a/arch/powerpc/crypto/aes-spe-regs.h b/arch/powerpc/crypto/aes-spe-regs.h index 30d217b399c3..2cc3a2caadae 100644 --- a/arch/powerpc/crypto/aes-spe-regs.h +++ b/arch/powerpc/crypto/aes-spe-regs.h @@ -18,7 +18,7 @@ #define rLN r7 /* length of data to be processed */ #define rIP r8 /* potiner to IV (CBC/CTR/XTS modes) */ #define rKT r9 /* pointer to tweak key (XTS mode) */ -#define rT0 r11 /* pointers to en-/decrpytion tables */ +#define rT0 r11 /* pointers to en-/decryption tables */ #define rT1 r10 #define rD0 r9 /* data */ #define rD1 r14 diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 290157e8d5b2..96430922dabb 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -434,7 +434,7 @@ extern void slb_set_size(u16 size); * function. Used in slb_allocate() and do_stab_bolted. The function * computed is: (protovsid*VSID_MULTIPLIER) % VSID_MODULUS * - * rt = register continaing the proto-VSID and into which the + * rt = register containing the proto-VSID and into which the * VSID will be stored * rx = scratch register (clobbered) * diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index fb9f376ae27b..7d34f3d3ca0e 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -57,7 +57,7 @@ struct pci_dn; /* * The struct is used to trace PE related EEH functionality. * In theory, there will have one instance of the struct to - * be created against particular PE. In nature, PEs corelate + * be created against particular PE. In nature, PEs correlate * to each other. the struct has to reflect that hierarchy in * order to easily pick up those affected PEs when one particular * PE has EEH errors. diff --git a/arch/powerpc/include/asm/nohash/32/pte-44x.h b/arch/powerpc/include/asm/nohash/32/pte-44x.h index fdab41c654ef..0656ff81e5b0 100644 --- a/arch/powerpc/include/asm/nohash/32/pte-44x.h +++ b/arch/powerpc/include/asm/nohash/32/pte-44x.h @@ -32,7 +32,7 @@ * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR * * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional - * TLB2 storage attibute fields. Those are: + * TLB2 storage attribute fields. Those are: * * TLB2: * 0...10 11 12 13 14 15 16...31 diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 9bb8ddf0be37..70b5cbc0a49c 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -802,7 +802,7 @@ struct opal_sg_entry { }; /* - * Candiate image SG list. + * Candidate image SG list. * * length = VER | length */ @@ -852,7 +852,7 @@ struct opal_i2c_request { * with individual elements being 16 bits wide to fetch the system * wide EPOW status. Each element in the buffer will contain the * EPOW status in it's bit representation for a particular EPOW sub - * class as defiend here. So multiple detailed EPOW status bits + * class as defined here. So multiple detailed EPOW status bits * specific for any sub class can be represented in a single buffer * element as it's bit representation. */ diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h index 925697968946..e08e829261b6 100644 --- a/arch/powerpc/include/asm/pmac_feature.h +++ b/arch/powerpc/include/asm/pmac_feature.h @@ -210,7 +210,7 @@ static inline long pmac_call_feature(int selector, struct device_node* node, /* PMAC_FTR_SOUND_CHIP_ENABLE (struct device_node* node, 0, int value) * enable/disable the sound chip, whatever it is and provided it can - * acually be controlled + * actually be controlled */ #define PMAC_FTR_SOUND_CHIP_ENABLE PMAC_FTR_DEF(9) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 009fab130cd8..c0c27bdbb069 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -224,7 +224,7 @@ struct thread_struct { unsigned int align_ctl; /* alignment handling control */ #ifdef CONFIG_PPC64 unsigned long start_tb; /* Start purr when proc switched in */ - unsigned long accum_tb; /* Total accumilated purr for process */ + unsigned long accum_tb; /* Total accumulated purr for process */ #ifdef CONFIG_HAVE_HW_BREAKPOINT struct perf_event *ptrace_bps[HBP_NUM]; /* diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h index 0427b0b53d2d..a1dc784d70e8 100644 --- a/arch/powerpc/include/asm/ps3av.h +++ b/arch/powerpc/include/asm/ps3av.h @@ -104,7 +104,7 @@ #define PS3AV_CMD_AV_INPUTLEN_16 0x02 #define PS3AV_CMD_AV_INPUTLEN_20 0x0a #define PS3AV_CMD_AV_INPUTLEN_24 0x0b -/* alayout */ +/* av_layout */ #define PS3AV_CMD_AV_LAYOUT_32 (1 << 0) #define PS3AV_CMD_AV_LAYOUT_44 (1 << 1) #define PS3AV_CMD_AV_LAYOUT_48 (1 << 2) diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h index 2eeaf80d41b7..4ba26dd259fd 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h @@ -96,7 +96,7 @@ static inline bool pte_user(pte_t pte) #define PTE_RPN_SHIFT (PAGE_SHIFT) #endif -/* The mask convered by the RPN must be a ULL on 32-bit platforms with +/* The mask covered by the RPN must be a ULL on 32-bit platforms with * 64-bit PTEs */ #if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index f280dd11243f..9dc2de5da35a 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h @@ -185,7 +185,7 @@ * x = processor mask * y = op. point index * z = processor freq. step index - * I haven't yet decyphered result codes + * I haven't yet deciphered result codes * */ #define SMU_CMD_POWER_COMMAND 0xaa diff --git a/arch/powerpc/include/asm/tsi108.h b/arch/powerpc/include/asm/tsi108.h index d531d9e173ef..c2a955bb0daa 100644 --- a/arch/powerpc/include/asm/tsi108.h +++ b/arch/powerpc/include/asm/tsi108.h @@ -77,7 +77,7 @@ * nodes if your board uses the Broadcom PHYs */ #define TSI108_PHY_MV88E 0 /* Marvel 88Exxxx PHY */ -#define TSI108_PHY_BCM54XX 1 /* Broardcom BCM54xx PHY */ +#define TSI108_PHY_BCM54XX 1 /* Broadcom BCM54xx PHY */ /* Global variables */ diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S index f8cd9fba4d35..c5e5a94d9892 100644 --- a/arch/powerpc/kernel/cpu_setup_6xx.S +++ b/arch/powerpc/kernel/cpu_setup_6xx.S @@ -156,7 +156,7 @@ setup_7410_workarounds: blr /* 740/750/7400/7410 - * Enable Store Gathering (SGE), Address Brodcast (ABE), + * Enable Store Gathering (SGE), Address Broadcast (ABE), * Branch History Table (BHTE), Branch Target ICache (BTIC) * Dynamic Power Management (DPM), Speculative (SPD) * Clear Instruction cache throttling (ICTC) diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 2714a3b81d24..389b0d3988dc 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -139,7 +139,7 @@ static void eeh_enable_irq(struct pci_dev *dev) * into it. * * That's just wrong.The warning in the core code is - * there to tell people to fix their assymetries in + * there to tell people to fix their asymmetries in * their own code, not by abusing the core information * to avoid it. * diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 488e6314f993..2d3b40fd9bac 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -453,7 +453,7 @@ exc_##n##_bad_stack: \ sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ b bad_stack_book3e; /* bad stack error */ -/* WARNING: If you change the layout of this stub, make sure you chcek +/* WARNING: If you change the layout of this stub, make sure you check * the debug exception handler which handles single stepping * into exceptions from userspace, and the MM code in * arch/powerpc/mm/tlb_nohash.c which patches the branch here diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 3759df52bd67..f71b79a8992b 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -82,7 +82,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus) /* If this is not a PHB, we only flush the hash table over * the area mapped by this bridge. We don't play with the PTE - * mappings since we might have to deal with sub-page alignemnts + * mappings since we might have to deal with sub-page alignments * so flushing the hash table is the only sane way to make sure * that no hash entries are covering that removed bridge area * while still allowing other busses overlapping those pages diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a2dd3b1276ff..c5c3ae2ef3c1 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -802,7 +802,7 @@ static void tm_reclaim_thread(struct thread_struct *thr, * this state. * We do this using the current MSR, rather tracking it in * some specific thread_struct bit, as it has the additional - * benifit of checking for a potential TM bad thing exception. + * benefit of checking for a potential TM bad thing exception. */ if (!MSR_TM_SUSPENDED(mfmsr())) return; diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index fb2fb3ea85e5..c82eed97bd22 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -698,7 +698,7 @@ static void check_location(struct seq_file *m, const char *c) /* * Format: * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] - * the '.' may be an abbrevation + * the '.' may be an abbreviation */ static void check_location_string(struct seq_file *m, const char *c) { diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c index 69abf844c2c3..94058c21a482 100644 --- a/arch/powerpc/lib/rheap.c +++ b/arch/powerpc/lib/rheap.c @@ -325,7 +325,7 @@ void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks, } EXPORT_SYMBOL_GPL(rh_init); -/* Attach a free memory region, coalesces regions if adjuscent */ +/* Attach a free memory region, coalesces regions if adjacent */ int rh_attach_region(rh_info_t * info, unsigned long start, int size) { rh_block_t *blk; diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 40e05e7f43de..dc57de118cf4 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -55,7 +55,7 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) * We need 14 to 65 bits of va for a tlibe of 4K page * With vpn we ignore the lower VPN_SHIFT bits already. * And top two bits are already ignored because we can - * only accomadate 76 bits in a 64 bit vpn with a VPN_SHIFT + * only accomodate 76 bits in a 64 bit vpn with a VPN_SHIFT * of 12. */ va = vpn << VPN_SHIFT; @@ -605,7 +605,7 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, * crashdump and all bets are off anyway. * * TODO: add batching support when enabled. remember, no dynamic memory here, - * athough there is the control page available... + * although there is the control page available... */ static void native_hpte_clear(void) { diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index ed7b0977072a..ef2142ff7dbd 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -51,7 +51,7 @@ static void spu_buff_add(unsigned long int value, int spu) * That way we can tell the difference between the * buffer being full versus empty. * - * ASSUPTION: the buffer_lock is held when this function + * ASSUMPTION: the buffer_lock is held when this function * is called to lock the buffer, head and tail. */ int full = 1; diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 97a1d40d8696..47086080a71f 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -992,7 +992,7 @@ static u64 check_and_compute_delta(u64 prev, u64 val) * than the previous value it will cause the delta and the counter to * have bogus values unless we rolled a counter over. If a coutner is * rolled back, it will be smaller, but within 256, which is the maximum - * number of events to rollback at once. If we dectect a rollback + * number of events to rollback at once. If we detect a rollback * return 0. This can lead to a small lack of precision in the * counters. */ diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 2da41b78cb6d..7b2ca16b1eb4 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -1298,7 +1298,7 @@ static void h_24x7_event_read(struct perf_event *event) __this_cpu_write(hv_24x7_txn_err, ret); } else { /* - * Assoicate the event with the HCALL request index, + * Associate the event with the HCALL request index, * so ->commit_txn() can quickly find/update count. */ i = request_buffer->num_requests - 1; diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h index 791455e7f5cf..634ef4082cdc 100644 --- a/arch/powerpc/perf/hv-24x7.h +++ b/arch/powerpc/perf/hv-24x7.h @@ -66,7 +66,7 @@ struct hv_24x7_result_element { /* -1 if @performance_domain does not refer to a virtual processor */ __be32 lpar_cfg_instance_id; - /* size = @result_element_data_size of cointaining result. */ + /* size = @result_element_data_size of containing result. */ __u64 element_data[1]; } __packed; diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index 6081fbd75330..add5a5374fa0 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -719,7 +719,7 @@ static void mpc512x_clk_setup_clock_tree(struct device_node *np, int busfreq) * most one of a mux, div, and gate each into one 'struct clk' * item * - PSC/MSCAN/SPDIF clock generation OTOH already is very - * specific and cannot get mapped to componsites (at least not + * specific and cannot get mapped to composites (at least not * a single one, maybe two of them, but then some of these * intermediate clock signals get referenced elsewhere (e.g. * in the clock frequency measurement, CFM) and thus need diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 14a582b21274..9027d7c48507 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -178,7 +178,7 @@ static int tce_build_cell(struct iommu_table *tbl, long index, long npages, * default for now.*/ #ifdef CELL_IOMMU_STRICT_PROTECTION /* to avoid referencing a global, we use a trick here to setup the - * protection bit. "prot" is setup to be 3 fields of 4 bits apprended + * protection bit. "prot" is setup to be 3 fields of 4 bits appended * together for each of the 3 supported direction values. It is then * shifted left so that the fields matching the desired direction * lands on the appropriate bits, and other bits are masked out. @@ -338,7 +338,7 @@ static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu, start_seg = base >> IO_SEGMENT_SHIFT; segments = size >> IO_SEGMENT_SHIFT; pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift); - /* PTEs for each segment must start on a 4K bounday */ + /* PTEs for each segment must start on a 4K boundary */ pages_per_segment = max(pages_per_segment, (1 << 12) / sizeof(unsigned long)); diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 54ee5743cb72..d06dcac66fcb 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -217,7 +217,7 @@ static void spider_irq_cascade(struct irq_desc *desc) chip->irq_eoi(&desc->irq_data); } -/* For hooking up the cascace we have a problem. Our device-tree is +/* For hooking up the cascade we have a problem. Our device-tree is * crap and we don't know on which BE iic interrupt we are hooked on at * least not the "standard" way. We can reconstitute it based on two * informations though: which BE node we are connected to and whether diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 3cbe38fad609..bb4a8e07c229 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -69,7 +69,7 @@ static DEFINE_SPINLOCK(spu_lock); * spu_full_list_lock and spu_full_list_mutex held, while iterating * through it requires either of these locks. * - * In addition spu_full_list_lock protects all assignmens to + * In addition spu_full_list_lock protects all assignments to * spu->mm. */ static LIST_HEAD(spu_full_list); @@ -253,7 +253,7 @@ static inline int __slb_present(struct copro_slb *slbs, int nr_slbs, * Setup the SPU kernel SLBs, in preparation for a context save/restore. We * need to map both the context save area, and the save/restore code. * - * Because the lscsa and code may cross segment boundaires, we check to see + * Because the lscsa and code may cross segment boundaries, we check to see * if mappings are required for the start and end of each range. We currently * assume that the mappings are smaller that one segment - if not, something * is seriously wrong. diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 2936a0044c04..06254467e4dd 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -866,7 +866,7 @@ void spufs_wbox_callback(struct spu *spu) * - end of the mapped area * * If the file is opened without O_NONBLOCK, we wait here until - * space is availabyl, but return when we have been able to + * space is available, but return when we have been able to * write something. */ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 9f79004e6d6f..cfacbee24d7b 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -435,7 +435,7 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) /* Note: we don't need to force_sig SIGTRAP on single-step * since we have TIF_SINGLESTEP set, thus the kernel will do - * it upon return from the syscall anyawy + * it upon return from the syscall anyway. */ if (unlikely(status & SPU_STATUS_SINGLE_STEP)) ret = -ERESTARTSYS; diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 998f632e7cce..460f5f31d5cb 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -622,7 +622,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx) /** * find_victim - find a lower priority context to preempt - * @ctx: canidate context for running + * @ctx: candidate context for running * * Returns the freed physical spu to run the new context on. */ diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 7553b6a77c64..6d6f277477aa 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -15,7 +15,7 @@ * This file thus provides a simple low level unified i2c interface for * powermac that covers the various types of i2c busses used in Apple machines. * For now, keywest, PMU and SMU, though we could add Cuda, or other bit - * banging busses found on older chipstes in earlier machines if we ever need + * banging busses found on older chipsets in earlier machines if we ever need * one of them. * * The drivers in this file are synchronous/blocking. In addition, the diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3a5ea8236db8..1fc53e015d29 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -197,7 +197,7 @@ static int pnv_ioda2_init_m64(struct pnv_phb *phb) /* * Strip off the segment used by the reserved PE, which is - * expected to be 0 or last one of PE capabicity. + * expected to be 0 or last one of PE capability. */ r = &phb->hose->mem_resources[1]; if (phb->ioda.reserved_pe_idx == 0) diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 3998e0f9a03b..1c428f06b14c 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -2,7 +2,7 @@ * The file intends to implement the platform dependent EEH operations on pseries. * Actually, the pseries platform is built based on RTAS heavily. That means the * pseries platform dependent EEH operations will be built on RTAS calls. The functions - * are devired from arch/powerpc/platforms/pseries/eeh.c and necessary cleanup has + * are derived from arch/powerpc/platforms/pseries/eeh.c and necessary cleanup has * been done. * * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2011. diff --git a/arch/powerpc/platforms/pseries/io_event_irq.c b/arch/powerpc/platforms/pseries/io_event_irq.c index 0240c4ff878a..f053bda64ee7 100644 --- a/arch/powerpc/platforms/pseries/io_event_irq.c +++ b/arch/powerpc/platforms/pseries/io_event_irq.c @@ -113,7 +113,7 @@ static struct pseries_io_event * ioei_find_event(struct rtas_error_log *elog) * - The owner of an event is determined by combinations of scope, * event type, and sub-type. There is no easy way to pre-sort clients * by scope or event type alone. For example, Torrent ISR route change - * event is reported with scope 0x00 (Not Applicatable) rather than + * event is reported with scope 0x00 (Not Applicable) rather than * 0x3B (Torrent-hub). It is better to let the clients to identify * who owns the event. */ diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 9883bc7ea007..9a79c2753a22 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -367,7 +367,7 @@ static void pseries_lpar_idle(void) { /* * Default handler to go into low thread priority and possibly - * low power mode by cedeing processor to hypervisor + * low power mode by ceding processor to hypervisor */ /* Indicate to hypervisor that we are idle. */ -- cgit v1.3-14-g43fede From 7075b30d04fa2df370ba5f904cd5c41271f45131 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 10 Jun 2016 17:11:25 +0200 Subject: pinctrl: sh-pfc: fix property name in bindings doc It must be "drive-strength", with a hyphen. Signed-off-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index 74e6ec0339d6..e4cf022c992e 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -72,7 +72,7 @@ Pin Configuration Node Properties: The pin configuration parameters use the generic pinconf bindings defined in pinctrl-bindings.txt in this directory. The supported parameters are -bias-disable, bias-pull-up, bias-pull-down, drive strength and power-source. For +bias-disable, bias-pull-up, bias-pull-down, drive-strength and power-source. For pins that have a configurable I/O voltage, the power-source value should be the nominal I/O voltage in millivolts. -- cgit v1.3-14-g43fede From bb3541f175a977198d128f3a4e13534e019754a3 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 14:14:44 +0200 Subject: KVM: x86: Fix typos Signed-off-by: Andrea Gelmini Signed-off-by: Paolo Bonzini --- Documentation/virtual/kvm/locking.txt | 4 ++-- arch/x86/kvm/mmu.c | 2 +- arch/x86/kvm/pmu_intel.c | 2 +- arch/x86/kvm/svm.c | 2 +- arch/x86/kvm/vmx.c | 2 +- arch/x86/kvm/x86.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/virtual/kvm/locking.txt b/Documentation/virtual/kvm/locking.txt index 19f94a6b9bb0..f2491a8c68b4 100644 --- a/Documentation/virtual/kvm/locking.txt +++ b/Documentation/virtual/kvm/locking.txt @@ -89,7 +89,7 @@ In mmu_spte_clear_track_bits(): old_spte = *spte; /* 'if' condition is satisfied. */ - if (old_spte.Accssed == 1 && + if (old_spte.Accessed == 1 && old_spte.W == 0) spte = 0ull; on fast page fault path: @@ -102,7 +102,7 @@ In mmu_spte_clear_track_bits(): old_spte = xchg(spte, 0ull) - if (old_spte.Accssed == 1) + if (old_spte.Accessed == 1) kvm_set_pfn_accessed(spte.pfn); if (old_spte.Dirty == 1) kvm_set_pfn_dirty(spte.pfn); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index def97b3a392b..837bf23c5b06 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -523,7 +523,7 @@ static void mmu_spte_set(u64 *sptep, u64 new_spte) } /* Rules for using mmu_spte_update: - * Update the state bits, it means the mapped pfn is not changged. + * Update the state bits, it means the mapped pfn is not changed. * * Whenever we overwrite a writable spte with a read-only one we * should flush remote TLBs. Otherwise rmap_write_protect diff --git a/arch/x86/kvm/pmu_intel.c b/arch/x86/kvm/pmu_intel.c index ab38af4f4947..9d4a8504a95a 100644 --- a/arch/x86/kvm/pmu_intel.c +++ b/arch/x86/kvm/pmu_intel.c @@ -93,7 +93,7 @@ static unsigned intel_find_fixed_event(int idx) return intel_arch_events[fixed_pmc_events[idx]].event_type; } -/* check if a PMC is enabled by comparising it with globl_ctrl bits. */ +/* check if a PMC is enabled by comparing it with globl_ctrl bits. */ static bool intel_pmc_is_enabled(struct kvm_pmc *pmc) { struct kvm_pmu *pmu = pmc_to_pmu(pmc); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1163e8173e5a..5ff292778110 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1572,7 +1572,7 @@ static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) { /* - * Any change of EFLAGS.VM is accompained by a reload of SS + * Any change of EFLAGS.VM is accompanied by a reload of SS * (caused by either a task switch or an inter-privilege IRET), * so we do not need to update the CPL here. */ diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fb93010beaa4..57ec6a4b4958 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3364,7 +3364,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) /* * Some cpus support VM_ENTRY_(LOAD|SAVE)_IA32_PERF_GLOBAL_CTRL - * but due to arrata below it can't be used. Workaround is to use + * but due to errata below it can't be used. Workaround is to use * msr load mechanism to switch IA32_PERF_GLOBAL_CTRL. * * VM Exit May Incorrectly Clear IA32_PERF_GLOBAL_CTRL [34:32] diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9d6a30593655..bf227212aebb 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8418,7 +8418,7 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons, /* * When producer of consumer is unregistered, we change back to * remapped mode, so we can re-use the current implementation - * when the irq is masked/disabed or the consumer side (KVM + * when the irq is masked/disabled or the consumer side (KVM * int this case doesn't want to receive the interrupts. */ ret = kvm_x86_ops->update_pi_irte(irqfd->kvm, prod->irq, irqfd->gsi, 0); -- cgit v1.3-14-g43fede From 956fff7189e586c646a179f00386d0ebf9f0fd8b Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 8 Jun 2016 20:02:09 +0300 Subject: spi: imx: Update DT binding documentation Mark "fsl,spi-num-chipselects" property as obsolete. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index 523341a0e113..8bc95e2fc47f 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -11,7 +11,6 @@ Required properties: - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt -- fsl,spi-num-chipselects : Contains the number of the chipselect - cs-gpios : Specifies the gpio pins to be used for chipselects. - clocks : Clock specifiers for both ipg and per clocks. - clock-names : Clock names should include both "ipg" and "per" @@ -21,6 +20,9 @@ See the clock consumer binding, Documentation/devicetree/bindings/dma/dma.txt - dma-names: DMA request names should include "tx" and "rx" if present. +Obsolete properties: +- fsl,spi-num-chipselects : Contains the number of the chipselect + Example: ecspi@70010000 { @@ -29,7 +31,6 @@ ecspi@70010000 { compatible = "fsl,imx51-ecspi"; reg = <0x70010000 0x4000>; interrupts = <36>; - fsl,spi-num-chipselects = <2>; cs-gpios = <&gpio3 24 0>, /* GPIO3_24 */ <&gpio3 25 0>; /* GPIO3_25 */ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>; -- cgit v1.3-14-g43fede From 35da60941e44dbf57868e67686dd24cc1a33125a Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Thu, 7 Jan 2016 15:40:56 -0800 Subject: pstore/ram: add Device Tree bindings ramoops is one of the remaining places where ARM vendors still rely on board-specific shims. Device Tree lets us replace those shims with generic code. These bindings mirror the ramoops module parameters, with two small differences: (1) dump_oops becomes an optional "no-dump-oops" property, since ramoops sets dump_oops=1 by default. (2) mem_type=1 becomes the more self-explanatory "unbuffered" property. Signed-off-by: Greg Hackmann [fixed platform_get_drvdata() crash, thanks to Brian Norris] [switched from u64 to u32 to simplify code, various whitespace fixes] [use dev_of_node() to gain code-elimination for CONFIG_OF=n] Signed-off-by: Kees Cook --- Documentation/devicetree/bindings/misc/ramoops.txt | 48 +++++++++++ Documentation/ramoops.txt | 6 +- fs/pstore/ram.c | 95 +++++++++++++++++++++- 3 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/misc/ramoops.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/misc/ramoops.txt b/Documentation/devicetree/bindings/misc/ramoops.txt new file mode 100644 index 000000000000..cd02cec67d38 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/ramoops.txt @@ -0,0 +1,48 @@ +Ramoops oops/panic logger +========================= + +ramoops provides persistent RAM storage for oops and panics, so they can be +recovered after a reboot. It is a backend to pstore, so this node is named +"ramoops" after the backend, rather than "pstore" which is the subsystem. + +Parts of this storage may be set aside for other persistent log buffers, such +as kernel log messages, or for optional ECC error-correction data. The total +size of these optional buffers must fit in the reserved region. + +Any remaining space will be used for a circular buffer of oops and panic +records. These records have a configurable size, with a size of 0 indicating +that they should be disabled. + +At least one of "record-size", "console-size", "ftrace-size", or "pmsg-size" +must be set non-zero, but are otherwise optional as listed below. + + +Required properties: + +- compatible: must be "ramoops" + +- memory-region: phandle to a region of memory that is preserved between + reboots + + +Optional properties: + +- ecc-size: enables ECC support and specifies ECC buffer size in bytes + (defaults to 0: no ECC) + +- record-size: maximum size in bytes of each dump done on oops/panic + (defaults to 0: disabled) + +- console-size: size in bytes of log buffer reserved for kernel messages + (defaults to 0: disabled) + +- ftrace-size: size in bytes of log buffer reserved for function tracing and + profiling (defaults to 0: disabled) + +- pmsg-size: size in bytes of log buffer reserved for userspace messages + (defaults to 0: disabled) + +- unbuffered: if present, use unbuffered mappings to map the reserved region + (defaults to buffered mappings) + +- no-dump-oops: if present, only dump panics (defaults to panics and oops) diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt index 5d8675615e59..9264bcab4099 100644 --- a/Documentation/ramoops.txt +++ b/Documentation/ramoops.txt @@ -45,7 +45,7 @@ corrupt, but usually it is restorable. 2. Setting the parameters -Setting the ramoops parameters can be done in 2 different manners: +Setting the ramoops parameters can be done in 3 different manners: 1. Use the module parameters (which have the names of the variables described as before). For quick debugging, you can also reserve parts of memory during boot @@ -54,7 +54,9 @@ Setting the ramoops parameters can be done in 2 different manners: kernel to use only the first 128 MB of memory, and place ECC-protected ramoops region at 128 MB boundary: "mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1" - 2. Use a platform device and set the platform data. The parameters can then + 2. Use Device Tree bindings, as described in + Documentation/device-tree/bindings/misc/ramoops.txt. + 3. Use a platform device and set the platform data. The parameters can then be set through that platform data. An example of doing that is: #include diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index d9668c2b43cb..47516a794011 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #define RAMOOPS_KERNMSG_HDR "====" #define MIN_MEM_SIZE 4096UL @@ -458,15 +460,98 @@ static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt, return 0; } +static int ramoops_parse_dt_size(struct platform_device *pdev, + const char *propname, u32 *value) +{ + u32 val32 = 0; + int ret; + + ret = of_property_read_u32(pdev->dev.of_node, propname, &val32); + if (ret < 0 && ret != -EINVAL) { + dev_err(&pdev->dev, "failed to parse property %s: %d\n", + propname, ret); + return ret; + } + + if (val32 > INT_MAX) { + dev_err(&pdev->dev, "%s %u > INT_MAX\n", propname, val32); + return -EOVERFLOW; + } + + *value = val32; + return 0; +} + +static int ramoops_parse_dt(struct platform_device *pdev, + struct ramoops_platform_data *pdata) +{ + struct device_node *of_node = pdev->dev.of_node; + struct device_node *mem_region; + struct resource res; + u32 value; + int ret; + + dev_dbg(&pdev->dev, "using Device Tree\n"); + + mem_region = of_parse_phandle(of_node, "memory-region", 0); + if (!mem_region) { + dev_err(&pdev->dev, "no memory-region phandle\n"); + return -ENODEV; + } + + ret = of_address_to_resource(mem_region, 0, &res); + of_node_put(mem_region); + if (ret) { + dev_err(&pdev->dev, + "failed to translate memory-region to resource: %d\n", + ret); + return ret; + } + + pdata->mem_size = resource_size(&res); + pdata->mem_address = res.start; + pdata->mem_type = of_property_read_bool(of_node, "unbuffered"); + pdata->dump_oops = !of_property_read_bool(of_node, "no-dump-oops"); + +#define parse_size(name, field) { \ + ret = ramoops_parse_dt_size(pdev, name, &value); \ + if (ret < 0) \ + return ret; \ + field = value; \ + } + + parse_size("record-size", pdata->record_size); + parse_size("console-size", pdata->console_size); + parse_size("ftrace-size", pdata->ftrace_size); + parse_size("pmsg-size", pdata->pmsg_size); + parse_size("ecc-size", pdata->ecc_info.ecc_size); + +#undef parse_size + + return 0; +} + static int ramoops_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct ramoops_platform_data *pdata = pdev->dev.platform_data; + struct ramoops_platform_data *pdata = dev->platform_data; struct ramoops_context *cxt = &oops_cxt; size_t dump_mem_sz; phys_addr_t paddr; int err = -EINVAL; + if (dev_of_node(dev) && !pdata) { + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + err = -ENOMEM; + goto fail_out; + } + + err = ramoops_parse_dt(pdev, pdata); + if (err < 0) + goto fail_out; + } + /* Only a single ramoops area allowed at a time, so fail extra * probes. */ @@ -596,11 +681,17 @@ static int ramoops_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id dt_match[] = { + { .compatible = "ramoops" }, + {} +}; + static struct platform_driver ramoops_driver = { .probe = ramoops_probe, .remove = ramoops_remove, .driver = { - .name = "ramoops", + .name = "ramoops", + .of_match_table = dt_match, }, }; -- cgit v1.3-14-g43fede From d41bfed091db0bdc2e0b2e847e0773a461f9e225 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Tue, 14 Jun 2016 01:46:01 +0200 Subject: dm raid: update Documentation about reshaping/takeover/additonal RAID types Signed-off-by: Heinz Mauelshagen Signed-off-by: Mike Snitzer --- Documentation/device-mapper/dm-raid.txt | 58 +++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt index df2d636b6088..e5b6497116f4 100644 --- a/Documentation/device-mapper/dm-raid.txt +++ b/Documentation/device-mapper/dm-raid.txt @@ -14,8 +14,12 @@ The target is named "raid" and it accepts the following parameters: <#raid_devs> [.. ] : + raid0 RAID0 striping (no resilience) raid1 RAID1 mirroring - raid4 RAID4 dedicated parity disk + raid4 RAID4 with dedicated last parity disk + raid5_n RAID5 with dedicated last parity disk suporting takeover + Same as raid4 + -Transitory layout raid5_la RAID5 left asymmetric - rotating parity 0 with data continuation raid5_ra RAID5 right asymmetric @@ -30,7 +34,19 @@ The target is named "raid" and it accepts the following parameters: - rotating parity N (right-to-left) with data restart raid6_nc RAID6 N continue - rotating parity N (right-to-left) with data continuation + raid6_n_6 RAID6 with dedicate parity disks + - parity and Q-syndrome on the last 2 disks; + laylout for takeover from/to raid4/raid5_n + raid6_la_6 Same as "raid_la" plus dedicated last Q-syndrome disk + - layout for takeover from raid5_la from/to raid6 + raid6_ra_6 Same as "raid5_ra" dedicated last Q-syndrome disk + - layout for takeover from raid5_ra from/to raid6 + raid6_ls_6 Same as "raid5_ls" dedicated last Q-syndrome disk + - layout for takeover from raid5_ls from/to raid6 + raid6_rs_6 Same as "raid5_rs" dedicated last Q-syndrome disk + - layout for takeover from raid5_rs from/to raid6 raid10 Various RAID10 inspired algorithms chosen by additional params + (see raid10_format and raid10_copies below) - RAID10: Striped Mirrors (aka 'Striping on top of mirrors') - RAID1E: Integrated Adjacent Stripe Mirroring - RAID1E: Integrated Offset Stripe Mirroring @@ -116,10 +132,41 @@ The target is named "raid" and it accepts the following parameters: Here we see layouts closely akin to 'RAID1E - Integrated Offset Stripe Mirroring'. + [delta_disks ] + The delta_disks option value (-251 < N < +251) triggers + device removal (negative value) or device addition (positive + value) to any reshape supporting raid levels 4/5/6 and 10. + RAID levels 4/5/6 allow for addition of devices (metadata + and data device tupel), raid10_near and raid10_offset only + allow for device addtion. raid10_far does not support any + reshaping at all. + A minimum of devices have to be kept to enforce resilience, + which is 3 devices for raid4/5 and 4 devices for raid6. + + [data_offset ] + This option value defines the offset into each data device + where the data starts. This is used to provide out-of-place + reshaping space to avoid writing over data whilst + changing the layout of stripes, hence an interruption/crash + may happen at any time without the risk of losing data. + E.g. when adding devices to an existing raid set during + forward reshaping, the out-of-place space will be allocated + at the beginning of each raid device. The kernel raid4/5/6/10 + MD personalities supporting such device addition will read the data from + the existing first stripes (those with smaller number of stripes) + starting at data_offset to fill up a new stripe with the larger + number of stripes, calculate the redundancy blocks (CRC/Q-syndrome) + and write that new stripe to offset 0. Same will be applied to all + N-1 other new stripes. This out-of-place scheme is used to change + the RAID type (i.e. the allocation algorithm) as well, e.g. + changing from raid5_ls to raid5_n. + <#raid_devs>: The number of devices composing the array. Each device consists of two entries. The first is the device containing the metadata (if any); the second is the one containing the - data. + data. A Maximum of 64 metadata/data device entries are supported + up to target version 1.8.0. + 1.9.0 supports up to 253 which is enforced by the used MD kernel runtime. If a drive has failed or is missing at creation time, a '-' can be given for both the metadata and data drives for a given position. @@ -207,7 +254,6 @@ include: "recover"- Initiate/continue a recover process. "check" - Initiate a check (i.e. a "scrub") of the array. "repair" - Initiate a repair of the array. - "reshape"- Currently unsupported (-EINVAL). Discard Support @@ -257,3 +303,9 @@ Version History 1.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check". 1.6.0 Add discard support (and devices_handle_discard_safely module param). 1.7.0 Add support for MD RAID0 mappings. +1.8.0 Explictely check for compatible flags in the superblock metadata + and reject to start the raid set if any are set by a newer + target version, thus avoiding data corruption on a raid set + with a reshape in progress. +1.9.0 Add support for RAID level takeover/reshape/region size + and set size reduction. -- cgit v1.3-14-g43fede From 2921b12362babf5af7d45e7b933637cfdfdf6a2a Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 1 Apr 2016 05:09:53 -0700 Subject: documentation: Add reference to 2014 RCU API LWN article Reported-by: Jim Roskind Signed-off-by: Paul E. McKenney --- Documentation/RCU/whatisRCU.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 111770ffa10e..13266cff42ff 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -5,6 +5,7 @@ to start learning about RCU: 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ 4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ +5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ What is RCU? -- cgit v1.3-14-g43fede From db4855b5a88535746558fb756512090fc1ce5607 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 1 Apr 2016 05:21:56 -0700 Subject: documentation: Add references to 2010 and 2014 Big API Tables Reported-by: Jim Roskind Signed-off-by: Paul E. McKenney --- Documentation/RCU/whatisRCU.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 13266cff42ff..204422719197 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -5,7 +5,9 @@ to start learning about RCU: 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ 4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ + 2010 Big API Table http://lwn.net/Articles/419086/ 5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ + 2014 Big API Table http://lwn.net/Articles/609973/ What is RCU? -- cgit v1.3-14-g43fede From c79dac758dc59f7461a721aaf65301cde8a448bc Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 20 Apr 2016 09:22:54 -0700 Subject: documentation: Add RCU_NONIDLE() restrictions to requirements Signed-off-by: Paul E. McKenney --- .../RCU/Design/Requirements/Requirements.html | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'Documentation') diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html index e7e24b3e86e2..ece410f40436 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.html +++ b/Documentation/RCU/Design/Requirements/Requirements.html @@ -2391,6 +2391,41 @@ and RCU_NONIDLE() on the other while inspecting idle-loop code. Steven Rostedt supplied _rcuidle event tracing, which is used quite heavily in the idle loop. +However, there are some restrictions on the code placed within +RCU_NONIDLE(): + +
    +
  1. Blocking is prohibited. + In practice, this is not a serious restriction given that idle + tasks are prohibited from blocking to begin with. +
  2. Although nesting RCU_NONIDLE() is permited, they cannot + nest indefinitely deeply. + However, given that they can be nested on the order of a million + deep, even on 32-bit systems, this should not be a serious + restriction. + This nesting limit would probably be reached long after the + compiler OOMed or the stack overflowed. +
  3. Any code path that enters RCU_NONIDLE() must sequence + out of that same RCU_NONIDLE(). + For example, the following is grossly illegal: + +
    +
    + 1     RCU_NONIDLE({
    + 2       do_something();
    + 3       goto bad_idea;  /* BUG!!! */
    + 4       do_something_else();});
    + 5   bad_idea:
    +	
    +
    + +

    + It is just as illegal to transfer control into the middle of + RCU_NONIDLE()'s argument. + Yes, in theory, you could transfer in as long as you also + transferred out, but in practice you could also expect to get sharply + worded review comments. +

It is similarly socially unacceptable to interrupt an -- cgit v1.3-14-g43fede From 14ef05754f397d468926187d285b9fee55603e86 Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Mon, 25 Apr 2016 07:36:59 +0100 Subject: Documentation: Fix spelling mistake Signed-off-by: Eric Engestrom Reviewed-by: Josh Triplett Signed-off-by: Paul E. McKenney --- Documentation/RCU/stallwarn.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/RCU/stallwarn.txt b/Documentation/RCU/stallwarn.txt index 0f7fb4298e7e..e93d04133fe7 100644 --- a/Documentation/RCU/stallwarn.txt +++ b/Documentation/RCU/stallwarn.txt @@ -49,7 +49,7 @@ rcupdate.rcu_task_stall_timeout This boot/sysfs parameter controls the RCU-tasks stall warning interval. A value of zero or less suppresses RCU-tasks stall warnings. A positive value sets the stall-warning interval - in jiffies. An RCU-tasks stall warning starts wtih the line: + in jiffies. An RCU-tasks stall warning starts with the line: INFO: rcu_tasks detected stalls on tasks: -- cgit v1.3-14-g43fede From 38c1e5e7b91dfa82547657269cabf5fba66c7a2b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 3 Jun 2016 13:55:00 +0200 Subject: pinctrl: qcom-ssbi: support for PM8058 The PM8058 is found in connection to the APQ8060 on the APQ8060 Dragonboard. Works the same as all others, just add the compatible string for this variant. Cc: Bjorn Andersson Cc: Andy Gross Reviewed-by: Stephen Boyd Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt | 1 + drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c | 1 + 2 files changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt index d74e631e10da..b484ba1af78c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt @@ -9,6 +9,7 @@ of PMIC's from Qualcomm. Definition: Should contain one of: "qcom,pm8018-mpp", "qcom,pm8038-mpp", + "qcom,pm8058-mpp", "qcom,pm8821-mpp", "qcom,pm8841-mpp", "qcom,pm8916-mpp", diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c index 9191727aff5e..0d1392fc32dd 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c @@ -744,6 +744,7 @@ static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl, static const struct of_device_id pm8xxx_mpp_of_match[] = { { .compatible = "qcom,pm8018-mpp" }, { .compatible = "qcom,pm8038-mpp" }, + { .compatible = "qcom,pm8058-mpp" }, { .compatible = "qcom,pm8917-mpp" }, { .compatible = "qcom,pm8821-mpp" }, { .compatible = "qcom,pm8921-mpp" }, -- cgit v1.3-14-g43fede From 5d76de61dd8cb89b7189ef7456fba921c547c398 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 15 Jun 2016 15:07:27 +0200 Subject: ASoC: adau17x1: Add support for specifying the MCLK using the CCF The devices from the ADAU17X1 family all have a MCLK clock input which supplies the master clock for the device. The master clock is used as the input clock for the PLL. Currently the MCLK rate as well as the desired PLL output frequency need to be supplied by calling snd_soc_dai_set_pll() form a machine driver. Add support for specifying the MCLK using the common clock framework. In addition to that also automatically configure the PLL to a suitable rate if the master clock was provided using the CCW. This allows to use the CODEC driver without any special configuration requirements from the machine driver. While the PLL output frequency can be configured over a (more or less) continuous range the narrowness of the range and the other constraints of the clocking tree usually only result in two output frequencies that will actually be chosen. One for 44.1kHz based rates and one for 48kHz based rates, these are the rates that the automatic PLL configuration will use. For the rare case where a non-standard setup is required a machine driver can disable the auto-configuration and configure a custom frequency using the existing mechanisms. If the common clock framework is not enabled clk_get() will return NULL and the driver will function as before and the clock rate needs to be configured manually. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/adi,adau17x1.txt | 8 + sound/soc/codecs/adau1761-i2c.c | 2 +- sound/soc/codecs/adau1761-spi.c | 2 +- sound/soc/codecs/adau1781-i2c.c | 2 +- sound/soc/codecs/adau1781-spi.c | 2 +- sound/soc/codecs/adau17x1.c | 219 +++++++++++++++------ sound/soc/codecs/adau17x1.h | 6 + 7 files changed, 179 insertions(+), 62 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/adi,adau17x1.txt b/Documentation/devicetree/bindings/sound/adi,adau17x1.txt index 8dbce0e18dda..1447dec28125 100644 --- a/Documentation/devicetree/bindings/sound/adi,adau17x1.txt +++ b/Documentation/devicetree/bindings/sound/adi,adau17x1.txt @@ -13,6 +13,11 @@ Required properties: - reg: The i2c address. Value depends on the state of ADDR0 and ADDR1, as wired in hardware. +Optional properties: + - clock-names: If provided must be "mclk". + - clocks: phandle + clock-specifiers for the clock that provides + the audio master clock for the device. + Examples: #include @@ -20,5 +25,8 @@ Examples: adau1361@38 { compatible = "adi,adau1761"; reg = <0x38>; + + clock-names = "mclk"; + clocks = <&audio_clock>; }; }; diff --git a/sound/soc/codecs/adau1761-i2c.c b/sound/soc/codecs/adau1761-i2c.c index 8de010f758cd..9e7f257f17f8 100644 --- a/sound/soc/codecs/adau1761-i2c.c +++ b/sound/soc/codecs/adau1761-i2c.c @@ -31,7 +31,7 @@ static int adau1761_i2c_probe(struct i2c_client *client, static int adau1761_i2c_remove(struct i2c_client *client) { - snd_soc_unregister_codec(&client->dev); + adau17x1_remove(&client->dev); return 0; } diff --git a/sound/soc/codecs/adau1761-spi.c b/sound/soc/codecs/adau1761-spi.c index d9171245bd9f..a0b214be759a 100644 --- a/sound/soc/codecs/adau1761-spi.c +++ b/sound/soc/codecs/adau1761-spi.c @@ -48,7 +48,7 @@ static int adau1761_spi_probe(struct spi_device *spi) static int adau1761_spi_remove(struct spi_device *spi) { - snd_soc_unregister_codec(&spi->dev); + adau17x1_remove(&spi->dev); return 0; } diff --git a/sound/soc/codecs/adau1781-i2c.c b/sound/soc/codecs/adau1781-i2c.c index 06cbca84cf02..7b9d1802d159 100644 --- a/sound/soc/codecs/adau1781-i2c.c +++ b/sound/soc/codecs/adau1781-i2c.c @@ -31,7 +31,7 @@ static int adau1781_i2c_probe(struct i2c_client *client, static int adau1781_i2c_remove(struct i2c_client *client) { - snd_soc_unregister_codec(&client->dev); + adau17x1_remove(&client->dev); return 0; } diff --git a/sound/soc/codecs/adau1781-spi.c b/sound/soc/codecs/adau1781-spi.c index 3d965a01b99c..9b233544d2e8 100644 --- a/sound/soc/codecs/adau1781-spi.c +++ b/sound/soc/codecs/adau1781-spi.c @@ -48,7 +48,7 @@ static int adau1781_spi_probe(struct spi_device *spi) static int adau1781_spi_remove(struct spi_device *spi) { - snd_soc_unregister_codec(&spi->dev); + adau17x1_remove(&spi->dev); return 0; } diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 66a6e061923d..439aa3ff1f99 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -303,6 +304,116 @@ bool adau17x1_has_dsp(struct adau *adau) } EXPORT_SYMBOL_GPL(adau17x1_has_dsp); +static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = dai->codec; + struct adau *adau = snd_soc_codec_get_drvdata(codec); + int ret; + + if (freq_in < 8000000 || freq_in > 27000000) + return -EINVAL; + + ret = adau_calc_pll_cfg(freq_in, freq_out, adau->pll_regs); + if (ret < 0) + return ret; + + /* The PLL register is 6 bytes long and can only be written at once. */ + ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL, + adau->pll_regs, ARRAY_SIZE(adau->pll_regs)); + if (ret) + return ret; + + adau->pll_freq = freq_out; + + return 0; +} + +static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec); + struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); + bool is_pll; + bool was_pll; + + switch (clk_id) { + case ADAU17X1_CLK_SRC_MCLK: + is_pll = false; + break; + case ADAU17X1_CLK_SRC_PLL_AUTO: + if (!adau->mclk) + return -EINVAL; + /* Fall-through */ + case ADAU17X1_CLK_SRC_PLL: + is_pll = true; + break; + default: + return -EINVAL; + } + + switch (adau->clk_src) { + case ADAU17X1_CLK_SRC_MCLK: + was_pll = false; + break; + case ADAU17X1_CLK_SRC_PLL: + case ADAU17X1_CLK_SRC_PLL_AUTO: + was_pll = true; + break; + default: + return -EINVAL; + } + + adau->sysclk = freq; + + if (is_pll != was_pll) { + if (is_pll) { + snd_soc_dapm_add_routes(dapm, + &adau17x1_dapm_pll_route, 1); + } else { + snd_soc_dapm_del_routes(dapm, + &adau17x1_dapm_pll_route, 1); + } + } + + adau->clk_src = clk_id; + + return 0; +} + +static int adau17x1_auto_pll(struct snd_soc_dai *dai, + struct snd_pcm_hw_params *params) +{ + struct adau *adau = snd_soc_dai_get_drvdata(dai); + unsigned int pll_rate; + + switch (params_rate(params)) { + case 48000: + case 8000: + case 12000: + case 16000: + case 24000: + case 32000: + case 96000: + pll_rate = 48000 * 1024; + break; + case 44100: + case 7350: + case 11025: + case 14700: + case 22050: + case 29400: + case 88200: + pll_rate = 44100 * 1024; + break; + default: + return -EINVAL; + } + + return adau17x1_set_dai_pll(dai, ADAU17X1_PLL, ADAU17X1_PLL_SRC_MCLK, + clk_get_rate(adau->mclk), pll_rate); +} + static int adau17x1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { @@ -312,10 +423,19 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, unsigned int freq; int ret; - if (adau->clk_src == ADAU17X1_CLK_SRC_PLL) + switch (adau->clk_src) { + case ADAU17X1_CLK_SRC_PLL_AUTO: + ret = adau17x1_auto_pll(dai, params); + if (ret) + return ret; + /* Fall-through */ + case ADAU17X1_CLK_SRC_PLL: freq = adau->pll_freq; - else + break; + default: freq = adau->sysclk; + break; + } if (freq % params_rate(params) != 0) return -EINVAL; @@ -387,62 +507,6 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, ADAU17X1_SERIAL_PORT1_DELAY_MASK, val); } -static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, - int source, unsigned int freq_in, unsigned int freq_out) -{ - struct snd_soc_codec *codec = dai->codec; - struct adau *adau = snd_soc_codec_get_drvdata(codec); - int ret; - - if (freq_in < 8000000 || freq_in > 27000000) - return -EINVAL; - - ret = adau_calc_pll_cfg(freq_in, freq_out, adau->pll_regs); - if (ret < 0) - return ret; - - /* The PLL register is 6 bytes long and can only be written at once. */ - ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL, - adau->pll_regs, ARRAY_SIZE(adau->pll_regs)); - if (ret) - return ret; - - adau->pll_freq = freq_out; - - return 0; -} - -static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec); - struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); - - switch (clk_id) { - case ADAU17X1_CLK_SRC_MCLK: - case ADAU17X1_CLK_SRC_PLL: - break; - default: - return -EINVAL; - } - - adau->sysclk = freq; - - if (adau->clk_src != clk_id) { - if (clk_id == ADAU17X1_CLK_SRC_PLL) { - snd_soc_dapm_add_routes(dapm, - &adau17x1_dapm_pll_route, 1); - } else { - snd_soc_dapm_del_routes(dapm, - &adau17x1_dapm_pll_route, 1); - } - } - - adau->clk_src = clk_id; - - return 0; -} - static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { @@ -827,6 +891,10 @@ int adau17x1_add_routes(struct snd_soc_codec *codec) ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes, ARRAY_SIZE(adau17x1_no_dsp_dapm_routes)); } + + if (adau->clk_src != ADAU17X1_CLK_SRC_MCLK) + snd_soc_dapm_add_routes(dapm, &adau17x1_dapm_pll_route, 1); + return ret; } EXPORT_SYMBOL_GPL(adau17x1_add_routes); @@ -849,6 +917,7 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap, const char *firmware_name) { struct adau *adau; + int ret; if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -857,6 +926,30 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap, if (!adau) return -ENOMEM; + adau->mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(adau->mclk)) { + if (PTR_ERR(adau->mclk) != -ENOENT) + return PTR_ERR(adau->mclk); + /* Clock is optional (for the driver) */ + adau->mclk = NULL; + } else if (adau->mclk) { + adau->clk_src = ADAU17X1_CLK_SRC_PLL_AUTO; + + /* + * Any valid PLL output rate will work at this point, use one + * that is likely to be chosen later as well. The register will + * be written when the PLL is powered up for the first time. + */ + ret = adau_calc_pll_cfg(clk_get_rate(adau->mclk), 48000 * 1024, + adau->pll_regs); + if (ret < 0) + return ret; + + ret = clk_prepare_enable(adau->mclk); + if (ret) + return ret; + } + adau->regmap = regmap; adau->switch_mode = switch_mode; adau->type = type; @@ -880,6 +973,16 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap, } EXPORT_SYMBOL_GPL(adau17x1_probe); +void adau17x1_remove(struct device *dev) +{ + struct adau *adau = dev_get_drvdata(dev); + + snd_soc_unregister_codec(dev); + if (adau->mclk) + clk_disable_unprepare(adau->mclk); +} +EXPORT_SYMBOL_GPL(adau17x1_remove); + MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code"); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index 5ae87a084d97..bf04b7efee40 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h @@ -22,13 +22,18 @@ enum adau17x1_pll_src { }; enum adau17x1_clk_src { + /* Automatically configure PLL based on the sample rate */ + ADAU17X1_CLK_SRC_PLL_AUTO, ADAU17X1_CLK_SRC_MCLK, ADAU17X1_CLK_SRC_PLL, }; +struct clk; + struct adau { unsigned int sysclk; unsigned int pll_freq; + struct clk *mclk; enum adau17x1_clk_src clk_src; enum adau17x1_type type; @@ -52,6 +57,7 @@ int adau17x1_add_routes(struct snd_soc_codec *codec); int adau17x1_probe(struct device *dev, struct regmap *regmap, enum adau17x1_type type, void (*switch_mode)(struct device *dev), const char *firmware_name); +void adau17x1_remove(struct device *dev); int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, enum adau17x1_micbias_voltage micbias); bool adau17x1_readable_register(struct device *dev, unsigned int reg); -- cgit v1.3-14-g43fede From e01957abd4cb3816a1eaaf191b16de182ebb333e Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Tue, 14 Jun 2016 11:13:04 -0500 Subject: hsi: Build hsi_boardinfo.c into hsi core if enabled If the HSI core is built as a module hsi_boardinfo may still be built-in as its Kconfig type is bool, which can cause build issues. Fix this by building this code into the HSI core when enabled. Reported-by: kbuild test robot Signed-off-by: Andrew F. Davis Signed-off-by: Sebastian Reichel --- Documentation/DocBook/device-drivers.tmpl | 2 +- drivers/hsi/Makefile | 3 +- drivers/hsi/hsi.c | 781 ------------------------------ drivers/hsi/hsi_core.c | 781 ++++++++++++++++++++++++++++++ 4 files changed, 784 insertions(+), 783 deletions(-) delete mode 100644 drivers/hsi/hsi.c create mode 100644 drivers/hsi/hsi_core.c (limited to 'Documentation') diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index de79efdad46c..c245e4eea560 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -511,7 +511,7 @@ X!Ilib/fonts/fonts.c !Iinclude/linux/hsi/hsi.h -!Edrivers/hsi/hsi.c +!Edrivers/hsi/hsi_core.c diff --git a/drivers/hsi/Makefile b/drivers/hsi/Makefile index 360371e134f1..96944783d584 100644 --- a/drivers/hsi/Makefile +++ b/drivers/hsi/Makefile @@ -1,7 +1,8 @@ # # Makefile for HSI # -obj-$(CONFIG_HSI_BOARDINFO) += hsi_boardinfo.o obj-$(CONFIG_HSI) += hsi.o +hsi-objs := hsi_core.o +hsi-$(CONFIG_HSI_BOARDINFO) += hsi_boardinfo.o obj-y += controllers/ obj-y += clients/ diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c deleted file mode 100644 index d7ce07ad67f3..000000000000 --- a/drivers/hsi/hsi.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * HSI core. - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Carlos Chinea - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hsi_core.h" - -static ssize_t modalias_show(struct device *dev, - struct device_attribute *a __maybe_unused, char *buf) -{ - return sprintf(buf, "hsi:%s\n", dev_name(dev)); -} -static DEVICE_ATTR_RO(modalias); - -static struct attribute *hsi_bus_dev_attrs[] = { - &dev_attr_modalias.attr, - NULL, -}; -ATTRIBUTE_GROUPS(hsi_bus_dev); - -static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); - - return 0; -} - -static int hsi_bus_match(struct device *dev, struct device_driver *driver) -{ - if (of_driver_match_device(dev, driver)) - return true; - - if (strcmp(dev_name(dev), driver->name) == 0) - return true; - - return false; -} - -static struct bus_type hsi_bus_type = { - .name = "hsi", - .dev_groups = hsi_bus_dev_groups, - .match = hsi_bus_match, - .uevent = hsi_bus_uevent, -}; - -static void hsi_client_release(struct device *dev) -{ - struct hsi_client *cl = to_hsi_client(dev); - - kfree(cl->tx_cfg.channels); - kfree(cl->rx_cfg.channels); - kfree(cl); -} - -struct hsi_client *hsi_new_client(struct hsi_port *port, - struct hsi_board_info *info) -{ - struct hsi_client *cl; - size_t size; - - cl = kzalloc(sizeof(*cl), GFP_KERNEL); - if (!cl) - goto err; - - cl->tx_cfg = info->tx_cfg; - if (cl->tx_cfg.channels) { - size = cl->tx_cfg.num_channels * sizeof(*cl->tx_cfg.channels); - cl->tx_cfg.channels = kmemdup(info->tx_cfg.channels, size, - GFP_KERNEL); - if (!cl->tx_cfg.channels) - goto err_tx; - } - - cl->rx_cfg = info->rx_cfg; - if (cl->rx_cfg.channels) { - size = cl->rx_cfg.num_channels * sizeof(*cl->rx_cfg.channels); - cl->rx_cfg.channels = kmemdup(info->rx_cfg.channels, size, - GFP_KERNEL); - if (!cl->rx_cfg.channels) - goto err_rx; - } - - cl->device.bus = &hsi_bus_type; - cl->device.parent = &port->device; - cl->device.release = hsi_client_release; - dev_set_name(&cl->device, "%s", info->name); - cl->device.platform_data = info->platform_data; - if (info->archdata) - cl->device.archdata = *info->archdata; - if (device_register(&cl->device) < 0) { - pr_err("hsi: failed to register client: %s\n", info->name); - put_device(&cl->device); - } - - return cl; -err_rx: - kfree(cl->tx_cfg.channels); -err_tx: - kfree(cl); -err: - return NULL; -} -EXPORT_SYMBOL_GPL(hsi_new_client); - -static void hsi_scan_board_info(struct hsi_controller *hsi) -{ - struct hsi_cl_info *cl_info; - struct hsi_port *p; - - list_for_each_entry(cl_info, &hsi_board_list, list) - if (cl_info->info.hsi_id == hsi->id) { - p = hsi_find_port_num(hsi, cl_info->info.port); - if (!p) - continue; - hsi_new_client(p, &cl_info->info); - } -} - -#ifdef CONFIG_OF -static struct hsi_board_info hsi_char_dev_info = { - .name = "hsi_char", -}; - -static int hsi_of_property_parse_mode(struct device_node *client, char *name, - unsigned int *result) -{ - const char *mode; - int err; - - err = of_property_read_string(client, name, &mode); - if (err < 0) - return err; - - if (strcmp(mode, "stream") == 0) - *result = HSI_MODE_STREAM; - else if (strcmp(mode, "frame") == 0) - *result = HSI_MODE_FRAME; - else - return -EINVAL; - - return 0; -} - -static int hsi_of_property_parse_flow(struct device_node *client, char *name, - unsigned int *result) -{ - const char *flow; - int err; - - err = of_property_read_string(client, name, &flow); - if (err < 0) - return err; - - if (strcmp(flow, "synchronized") == 0) - *result = HSI_FLOW_SYNC; - else if (strcmp(flow, "pipeline") == 0) - *result = HSI_FLOW_PIPE; - else - return -EINVAL; - - return 0; -} - -static int hsi_of_property_parse_arb_mode(struct device_node *client, - char *name, unsigned int *result) -{ - const char *arb_mode; - int err; - - err = of_property_read_string(client, name, &arb_mode); - if (err < 0) - return err; - - if (strcmp(arb_mode, "round-robin") == 0) - *result = HSI_ARB_RR; - else if (strcmp(arb_mode, "priority") == 0) - *result = HSI_ARB_PRIO; - else - return -EINVAL; - - return 0; -} - -static void hsi_add_client_from_dt(struct hsi_port *port, - struct device_node *client) -{ - struct hsi_client *cl; - struct hsi_channel channel; - struct property *prop; - char name[32]; - int length, cells, err, i, max_chan, mode; - - cl = kzalloc(sizeof(*cl), GFP_KERNEL); - if (!cl) - return; - - err = of_modalias_node(client, name, sizeof(name)); - if (err) - goto err; - - dev_set_name(&cl->device, "%s", name); - - err = hsi_of_property_parse_mode(client, "hsi-mode", &mode); - if (err) { - err = hsi_of_property_parse_mode(client, "hsi-rx-mode", - &cl->rx_cfg.mode); - if (err) - goto err; - - err = hsi_of_property_parse_mode(client, "hsi-tx-mode", - &cl->tx_cfg.mode); - if (err) - goto err; - } else { - cl->rx_cfg.mode = mode; - cl->tx_cfg.mode = mode; - } - - err = of_property_read_u32(client, "hsi-speed-kbps", - &cl->tx_cfg.speed); - if (err) - goto err; - cl->rx_cfg.speed = cl->tx_cfg.speed; - - err = hsi_of_property_parse_flow(client, "hsi-flow", - &cl->rx_cfg.flow); - if (err) - goto err; - - err = hsi_of_property_parse_arb_mode(client, "hsi-arb-mode", - &cl->rx_cfg.arb_mode); - if (err) - goto err; - - prop = of_find_property(client, "hsi-channel-ids", &length); - if (!prop) { - err = -EINVAL; - goto err; - } - - cells = length / sizeof(u32); - - cl->rx_cfg.num_channels = cells; - cl->tx_cfg.num_channels = cells; - - cl->rx_cfg.channels = kzalloc(cells * sizeof(channel), GFP_KERNEL); - if (!cl->rx_cfg.channels) { - err = -ENOMEM; - goto err; - } - - cl->tx_cfg.channels = kzalloc(cells * sizeof(channel), GFP_KERNEL); - if (!cl->tx_cfg.channels) { - err = -ENOMEM; - goto err2; - } - - max_chan = 0; - for (i = 0; i < cells; i++) { - err = of_property_read_u32_index(client, "hsi-channel-ids", i, - &channel.id); - if (err) - goto err3; - - err = of_property_read_string_index(client, "hsi-channel-names", - i, &channel.name); - if (err) - channel.name = NULL; - - if (channel.id > max_chan) - max_chan = channel.id; - - cl->rx_cfg.channels[i] = channel; - cl->tx_cfg.channels[i] = channel; - } - - cl->rx_cfg.num_hw_channels = max_chan + 1; - cl->tx_cfg.num_hw_channels = max_chan + 1; - - cl->device.bus = &hsi_bus_type; - cl->device.parent = &port->device; - cl->device.release = hsi_client_release; - cl->device.of_node = client; - - if (device_register(&cl->device) < 0) { - pr_err("hsi: failed to register client: %s\n", name); - put_device(&cl->device); - } - - return; - -err3: - kfree(cl->tx_cfg.channels); -err2: - kfree(cl->rx_cfg.channels); -err: - kfree(cl); - pr_err("hsi client: missing or incorrect of property: err=%d\n", err); -} - -void hsi_add_clients_from_dt(struct hsi_port *port, struct device_node *clients) -{ - struct device_node *child; - - /* register hsi-char device */ - hsi_new_client(port, &hsi_char_dev_info); - - for_each_available_child_of_node(clients, child) - hsi_add_client_from_dt(port, child); -} -EXPORT_SYMBOL_GPL(hsi_add_clients_from_dt); -#endif - -int hsi_remove_client(struct device *dev, void *data __maybe_unused) -{ - device_unregister(dev); - - return 0; -} -EXPORT_SYMBOL_GPL(hsi_remove_client); - -static int hsi_remove_port(struct device *dev, void *data __maybe_unused) -{ - device_for_each_child(dev, NULL, hsi_remove_client); - device_unregister(dev); - - return 0; -} - -static void hsi_controller_release(struct device *dev) -{ - struct hsi_controller *hsi = to_hsi_controller(dev); - - kfree(hsi->port); - kfree(hsi); -} - -static void hsi_port_release(struct device *dev) -{ - kfree(to_hsi_port(dev)); -} - -/** - * hsi_unregister_port - Unregister an HSI port - * @port: The HSI port to unregister - */ -void hsi_port_unregister_clients(struct hsi_port *port) -{ - device_for_each_child(&port->device, NULL, hsi_remove_client); -} -EXPORT_SYMBOL_GPL(hsi_port_unregister_clients); - -/** - * hsi_unregister_controller - Unregister an HSI controller - * @hsi: The HSI controller to register - */ -void hsi_unregister_controller(struct hsi_controller *hsi) -{ - device_for_each_child(&hsi->device, NULL, hsi_remove_port); - device_unregister(&hsi->device); -} -EXPORT_SYMBOL_GPL(hsi_unregister_controller); - -/** - * hsi_register_controller - Register an HSI controller and its ports - * @hsi: The HSI controller to register - * - * Returns -errno on failure, 0 on success. - */ -int hsi_register_controller(struct hsi_controller *hsi) -{ - unsigned int i; - int err; - - err = device_add(&hsi->device); - if (err < 0) - return err; - for (i = 0; i < hsi->num_ports; i++) { - hsi->port[i]->device.parent = &hsi->device; - err = device_add(&hsi->port[i]->device); - if (err < 0) - goto out; - } - /* Populate HSI bus with HSI clients */ - hsi_scan_board_info(hsi); - - return 0; -out: - while (i-- > 0) - device_del(&hsi->port[i]->device); - device_del(&hsi->device); - - return err; -} -EXPORT_SYMBOL_GPL(hsi_register_controller); - -/** - * hsi_register_client_driver - Register an HSI client to the HSI bus - * @drv: HSI client driver to register - * - * Returns -errno on failure, 0 on success. - */ -int hsi_register_client_driver(struct hsi_client_driver *drv) -{ - drv->driver.bus = &hsi_bus_type; - - return driver_register(&drv->driver); -} -EXPORT_SYMBOL_GPL(hsi_register_client_driver); - -static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused) -{ - return 0; -} - -static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused) -{ - return 0; -} - -/** - * hsi_put_controller - Free an HSI controller - * - * @hsi: Pointer to the HSI controller to freed - * - * HSI controller drivers should only use this function if they need - * to free their allocated hsi_controller structures before a successful - * call to hsi_register_controller. Other use is not allowed. - */ -void hsi_put_controller(struct hsi_controller *hsi) -{ - unsigned int i; - - if (!hsi) - return; - - for (i = 0; i < hsi->num_ports; i++) - if (hsi->port && hsi->port[i]) - put_device(&hsi->port[i]->device); - put_device(&hsi->device); -} -EXPORT_SYMBOL_GPL(hsi_put_controller); - -/** - * hsi_alloc_controller - Allocate an HSI controller and its ports - * @n_ports: Number of ports on the HSI controller - * @flags: Kernel allocation flags - * - * Return NULL on failure or a pointer to an hsi_controller on success. - */ -struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) -{ - struct hsi_controller *hsi; - struct hsi_port **port; - unsigned int i; - - if (!n_ports) - return NULL; - - hsi = kzalloc(sizeof(*hsi), flags); - if (!hsi) - return NULL; - port = kzalloc(sizeof(*port)*n_ports, flags); - if (!port) { - kfree(hsi); - return NULL; - } - hsi->num_ports = n_ports; - hsi->port = port; - hsi->device.release = hsi_controller_release; - device_initialize(&hsi->device); - - for (i = 0; i < n_ports; i++) { - port[i] = kzalloc(sizeof(**port), flags); - if (port[i] == NULL) - goto out; - port[i]->num = i; - port[i]->async = hsi_dummy_msg; - port[i]->setup = hsi_dummy_cl; - port[i]->flush = hsi_dummy_cl; - port[i]->start_tx = hsi_dummy_cl; - port[i]->stop_tx = hsi_dummy_cl; - port[i]->release = hsi_dummy_cl; - mutex_init(&port[i]->lock); - ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); - dev_set_name(&port[i]->device, "port%d", i); - hsi->port[i]->device.release = hsi_port_release; - device_initialize(&hsi->port[i]->device); - } - - return hsi; -out: - hsi_put_controller(hsi); - - return NULL; -} -EXPORT_SYMBOL_GPL(hsi_alloc_controller); - -/** - * hsi_free_msg - Free an HSI message - * @msg: Pointer to the HSI message - * - * Client is responsible to free the buffers pointed by the scatterlists. - */ -void hsi_free_msg(struct hsi_msg *msg) -{ - if (!msg) - return; - sg_free_table(&msg->sgt); - kfree(msg); -} -EXPORT_SYMBOL_GPL(hsi_free_msg); - -/** - * hsi_alloc_msg - Allocate an HSI message - * @nents: Number of memory entries - * @flags: Kernel allocation flags - * - * nents can be 0. This mainly makes sense for read transfer. - * In that case, HSI drivers will call the complete callback when - * there is data to be read without consuming it. - * - * Return NULL on failure or a pointer to an hsi_msg on success. - */ -struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags) -{ - struct hsi_msg *msg; - int err; - - msg = kzalloc(sizeof(*msg), flags); - if (!msg) - return NULL; - - if (!nents) - return msg; - - err = sg_alloc_table(&msg->sgt, nents, flags); - if (unlikely(err)) { - kfree(msg); - msg = NULL; - } - - return msg; -} -EXPORT_SYMBOL_GPL(hsi_alloc_msg); - -/** - * hsi_async - Submit an HSI transfer to the controller - * @cl: HSI client sending the transfer - * @msg: The HSI transfer passed to controller - * - * The HSI message must have the channel, ttype, complete and destructor - * fields set beforehand. If nents > 0 then the client has to initialize - * also the scatterlists to point to the buffers to write to or read from. - * - * HSI controllers relay on pre-allocated buffers from their clients and they - * do not allocate buffers on their own. - * - * Once the HSI message transfer finishes, the HSI controller calls the - * complete callback with the status and actual_len fields of the HSI message - * updated. The complete callback can be called before returning from - * hsi_async. - * - * Returns -errno on failure or 0 on success - */ -int hsi_async(struct hsi_client *cl, struct hsi_msg *msg) -{ - struct hsi_port *port = hsi_get_port(cl); - - if (!hsi_port_claimed(cl)) - return -EACCES; - - WARN_ON_ONCE(!msg->destructor || !msg->complete); - msg->cl = cl; - - return port->async(msg); -} -EXPORT_SYMBOL_GPL(hsi_async); - -/** - * hsi_claim_port - Claim the HSI client's port - * @cl: HSI client that wants to claim its port - * @share: Flag to indicate if the client wants to share the port or not. - * - * Returns -errno on failure, 0 on success. - */ -int hsi_claim_port(struct hsi_client *cl, unsigned int share) -{ - struct hsi_port *port = hsi_get_port(cl); - int err = 0; - - mutex_lock(&port->lock); - if ((port->claimed) && (!port->shared || !share)) { - err = -EBUSY; - goto out; - } - if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) { - err = -ENODEV; - goto out; - } - port->claimed++; - port->shared = !!share; - cl->pclaimed = 1; -out: - mutex_unlock(&port->lock); - - return err; -} -EXPORT_SYMBOL_GPL(hsi_claim_port); - -/** - * hsi_release_port - Release the HSI client's port - * @cl: HSI client which previously claimed its port - */ -void hsi_release_port(struct hsi_client *cl) -{ - struct hsi_port *port = hsi_get_port(cl); - - mutex_lock(&port->lock); - /* Allow HW driver to do some cleanup */ - port->release(cl); - if (cl->pclaimed) - port->claimed--; - BUG_ON(port->claimed < 0); - cl->pclaimed = 0; - if (!port->claimed) - port->shared = 0; - module_put(to_hsi_controller(port->device.parent)->owner); - mutex_unlock(&port->lock); -} -EXPORT_SYMBOL_GPL(hsi_release_port); - -static int hsi_event_notifier_call(struct notifier_block *nb, - unsigned long event, void *data __maybe_unused) -{ - struct hsi_client *cl = container_of(nb, struct hsi_client, nb); - - (*cl->ehandler)(cl, event); - - return 0; -} - -/** - * hsi_register_port_event - Register a client to receive port events - * @cl: HSI client that wants to receive port events - * @handler: Event handler callback - * - * Clients should register a callback to be able to receive - * events from the ports. Registration should happen after - * claiming the port. - * The handler can be called in interrupt context. - * - * Returns -errno on error, or 0 on success. - */ -int hsi_register_port_event(struct hsi_client *cl, - void (*handler)(struct hsi_client *, unsigned long)) -{ - struct hsi_port *port = hsi_get_port(cl); - - if (!handler || cl->ehandler) - return -EINVAL; - if (!hsi_port_claimed(cl)) - return -EACCES; - cl->ehandler = handler; - cl->nb.notifier_call = hsi_event_notifier_call; - - return atomic_notifier_chain_register(&port->n_head, &cl->nb); -} -EXPORT_SYMBOL_GPL(hsi_register_port_event); - -/** - * hsi_unregister_port_event - Stop receiving port events for a client - * @cl: HSI client that wants to stop receiving port events - * - * Clients should call this function before releasing their associated - * port. - * - * Returns -errno on error, or 0 on success. - */ -int hsi_unregister_port_event(struct hsi_client *cl) -{ - struct hsi_port *port = hsi_get_port(cl); - int err; - - WARN_ON(!hsi_port_claimed(cl)); - - err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); - if (!err) - cl->ehandler = NULL; - - return err; -} -EXPORT_SYMBOL_GPL(hsi_unregister_port_event); - -/** - * hsi_event - Notifies clients about port events - * @port: Port where the event occurred - * @event: The event type - * - * Clients should not be concerned about wake line behavior. However, due - * to a race condition in HSI HW protocol, clients need to be notified - * about wake line changes, so they can implement a workaround for it. - * - * Events: - * HSI_EVENT_START_RX - Incoming wake line high - * HSI_EVENT_STOP_RX - Incoming wake line down - * - * Returns -errno on error, or 0 on success. - */ -int hsi_event(struct hsi_port *port, unsigned long event) -{ - return atomic_notifier_call_chain(&port->n_head, event, NULL); -} -EXPORT_SYMBOL_GPL(hsi_event); - -/** - * hsi_get_channel_id_by_name - acquire channel id by channel name - * @cl: HSI client, which uses the channel - * @name: name the channel is known under - * - * Clients can call this function to get the hsi channel ids similar to - * requesting IRQs or GPIOs by name. This function assumes the same - * channel configuration is used for RX and TX. - * - * Returns -errno on error or channel id on success. - */ -int hsi_get_channel_id_by_name(struct hsi_client *cl, char *name) -{ - int i; - - if (!cl->rx_cfg.channels) - return -ENOENT; - - for (i = 0; i < cl->rx_cfg.num_channels; i++) - if (!strcmp(cl->rx_cfg.channels[i].name, name)) - return cl->rx_cfg.channels[i].id; - - return -ENXIO; -} -EXPORT_SYMBOL_GPL(hsi_get_channel_id_by_name); - -static int __init hsi_init(void) -{ - return bus_register(&hsi_bus_type); -} -postcore_initcall(hsi_init); - -static void __exit hsi_exit(void) -{ - bus_unregister(&hsi_bus_type); -} -module_exit(hsi_exit); - -MODULE_AUTHOR("Carlos Chinea "); -MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/hsi/hsi_core.c b/drivers/hsi/hsi_core.c new file mode 100644 index 000000000000..d7ce07ad67f3 --- /dev/null +++ b/drivers/hsi/hsi_core.c @@ -0,0 +1,781 @@ +/* + * HSI core. + * + * Copyright (C) 2010 Nokia Corporation. All rights reserved. + * + * Contact: Carlos Chinea + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hsi_core.h" + +static ssize_t modalias_show(struct device *dev, + struct device_attribute *a __maybe_unused, char *buf) +{ + return sprintf(buf, "hsi:%s\n", dev_name(dev)); +} +static DEVICE_ATTR_RO(modalias); + +static struct attribute *hsi_bus_dev_attrs[] = { + &dev_attr_modalias.attr, + NULL, +}; +ATTRIBUTE_GROUPS(hsi_bus_dev); + +static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); + + return 0; +} + +static int hsi_bus_match(struct device *dev, struct device_driver *driver) +{ + if (of_driver_match_device(dev, driver)) + return true; + + if (strcmp(dev_name(dev), driver->name) == 0) + return true; + + return false; +} + +static struct bus_type hsi_bus_type = { + .name = "hsi", + .dev_groups = hsi_bus_dev_groups, + .match = hsi_bus_match, + .uevent = hsi_bus_uevent, +}; + +static void hsi_client_release(struct device *dev) +{ + struct hsi_client *cl = to_hsi_client(dev); + + kfree(cl->tx_cfg.channels); + kfree(cl->rx_cfg.channels); + kfree(cl); +} + +struct hsi_client *hsi_new_client(struct hsi_port *port, + struct hsi_board_info *info) +{ + struct hsi_client *cl; + size_t size; + + cl = kzalloc(sizeof(*cl), GFP_KERNEL); + if (!cl) + goto err; + + cl->tx_cfg = info->tx_cfg; + if (cl->tx_cfg.channels) { + size = cl->tx_cfg.num_channels * sizeof(*cl->tx_cfg.channels); + cl->tx_cfg.channels = kmemdup(info->tx_cfg.channels, size, + GFP_KERNEL); + if (!cl->tx_cfg.channels) + goto err_tx; + } + + cl->rx_cfg = info->rx_cfg; + if (cl->rx_cfg.channels) { + size = cl->rx_cfg.num_channels * sizeof(*cl->rx_cfg.channels); + cl->rx_cfg.channels = kmemdup(info->rx_cfg.channels, size, + GFP_KERNEL); + if (!cl->rx_cfg.channels) + goto err_rx; + } + + cl->device.bus = &hsi_bus_type; + cl->device.parent = &port->device; + cl->device.release = hsi_client_release; + dev_set_name(&cl->device, "%s", info->name); + cl->device.platform_data = info->platform_data; + if (info->archdata) + cl->device.archdata = *info->archdata; + if (device_register(&cl->device) < 0) { + pr_err("hsi: failed to register client: %s\n", info->name); + put_device(&cl->device); + } + + return cl; +err_rx: + kfree(cl->tx_cfg.channels); +err_tx: + kfree(cl); +err: + return NULL; +} +EXPORT_SYMBOL_GPL(hsi_new_client); + +static void hsi_scan_board_info(struct hsi_controller *hsi) +{ + struct hsi_cl_info *cl_info; + struct hsi_port *p; + + list_for_each_entry(cl_info, &hsi_board_list, list) + if (cl_info->info.hsi_id == hsi->id) { + p = hsi_find_port_num(hsi, cl_info->info.port); + if (!p) + continue; + hsi_new_client(p, &cl_info->info); + } +} + +#ifdef CONFIG_OF +static struct hsi_board_info hsi_char_dev_info = { + .name = "hsi_char", +}; + +static int hsi_of_property_parse_mode(struct device_node *client, char *name, + unsigned int *result) +{ + const char *mode; + int err; + + err = of_property_read_string(client, name, &mode); + if (err < 0) + return err; + + if (strcmp(mode, "stream") == 0) + *result = HSI_MODE_STREAM; + else if (strcmp(mode, "frame") == 0) + *result = HSI_MODE_FRAME; + else + return -EINVAL; + + return 0; +} + +static int hsi_of_property_parse_flow(struct device_node *client, char *name, + unsigned int *result) +{ + const char *flow; + int err; + + err = of_property_read_string(client, name, &flow); + if (err < 0) + return err; + + if (strcmp(flow, "synchronized") == 0) + *result = HSI_FLOW_SYNC; + else if (strcmp(flow, "pipeline") == 0) + *result = HSI_FLOW_PIPE; + else + return -EINVAL; + + return 0; +} + +static int hsi_of_property_parse_arb_mode(struct device_node *client, + char *name, unsigned int *result) +{ + const char *arb_mode; + int err; + + err = of_property_read_string(client, name, &arb_mode); + if (err < 0) + return err; + + if (strcmp(arb_mode, "round-robin") == 0) + *result = HSI_ARB_RR; + else if (strcmp(arb_mode, "priority") == 0) + *result = HSI_ARB_PRIO; + else + return -EINVAL; + + return 0; +} + +static void hsi_add_client_from_dt(struct hsi_port *port, + struct device_node *client) +{ + struct hsi_client *cl; + struct hsi_channel channel; + struct property *prop; + char name[32]; + int length, cells, err, i, max_chan, mode; + + cl = kzalloc(sizeof(*cl), GFP_KERNEL); + if (!cl) + return; + + err = of_modalias_node(client, name, sizeof(name)); + if (err) + goto err; + + dev_set_name(&cl->device, "%s", name); + + err = hsi_of_property_parse_mode(client, "hsi-mode", &mode); + if (err) { + err = hsi_of_property_parse_mode(client, "hsi-rx-mode", + &cl->rx_cfg.mode); + if (err) + goto err; + + err = hsi_of_property_parse_mode(client, "hsi-tx-mode", + &cl->tx_cfg.mode); + if (err) + goto err; + } else { + cl->rx_cfg.mode = mode; + cl->tx_cfg.mode = mode; + } + + err = of_property_read_u32(client, "hsi-speed-kbps", + &cl->tx_cfg.speed); + if (err) + goto err; + cl->rx_cfg.speed = cl->tx_cfg.speed; + + err = hsi_of_property_parse_flow(client, "hsi-flow", + &cl->rx_cfg.flow); + if (err) + goto err; + + err = hsi_of_property_parse_arb_mode(client, "hsi-arb-mode", + &cl->rx_cfg.arb_mode); + if (err) + goto err; + + prop = of_find_property(client, "hsi-channel-ids", &length); + if (!prop) { + err = -EINVAL; + goto err; + } + + cells = length / sizeof(u32); + + cl->rx_cfg.num_channels = cells; + cl->tx_cfg.num_channels = cells; + + cl->rx_cfg.channels = kzalloc(cells * sizeof(channel), GFP_KERNEL); + if (!cl->rx_cfg.channels) { + err = -ENOMEM; + goto err; + } + + cl->tx_cfg.channels = kzalloc(cells * sizeof(channel), GFP_KERNEL); + if (!cl->tx_cfg.channels) { + err = -ENOMEM; + goto err2; + } + + max_chan = 0; + for (i = 0; i < cells; i++) { + err = of_property_read_u32_index(client, "hsi-channel-ids", i, + &channel.id); + if (err) + goto err3; + + err = of_property_read_string_index(client, "hsi-channel-names", + i, &channel.name); + if (err) + channel.name = NULL; + + if (channel.id > max_chan) + max_chan = channel.id; + + cl->rx_cfg.channels[i] = channel; + cl->tx_cfg.channels[i] = channel; + } + + cl->rx_cfg.num_hw_channels = max_chan + 1; + cl->tx_cfg.num_hw_channels = max_chan + 1; + + cl->device.bus = &hsi_bus_type; + cl->device.parent = &port->device; + cl->device.release = hsi_client_release; + cl->device.of_node = client; + + if (device_register(&cl->device) < 0) { + pr_err("hsi: failed to register client: %s\n", name); + put_device(&cl->device); + } + + return; + +err3: + kfree(cl->tx_cfg.channels); +err2: + kfree(cl->rx_cfg.channels); +err: + kfree(cl); + pr_err("hsi client: missing or incorrect of property: err=%d\n", err); +} + +void hsi_add_clients_from_dt(struct hsi_port *port, struct device_node *clients) +{ + struct device_node *child; + + /* register hsi-char device */ + hsi_new_client(port, &hsi_char_dev_info); + + for_each_available_child_of_node(clients, child) + hsi_add_client_from_dt(port, child); +} +EXPORT_SYMBOL_GPL(hsi_add_clients_from_dt); +#endif + +int hsi_remove_client(struct device *dev, void *data __maybe_unused) +{ + device_unregister(dev); + + return 0; +} +EXPORT_SYMBOL_GPL(hsi_remove_client); + +static int hsi_remove_port(struct device *dev, void *data __maybe_unused) +{ + device_for_each_child(dev, NULL, hsi_remove_client); + device_unregister(dev); + + return 0; +} + +static void hsi_controller_release(struct device *dev) +{ + struct hsi_controller *hsi = to_hsi_controller(dev); + + kfree(hsi->port); + kfree(hsi); +} + +static void hsi_port_release(struct device *dev) +{ + kfree(to_hsi_port(dev)); +} + +/** + * hsi_unregister_port - Unregister an HSI port + * @port: The HSI port to unregister + */ +void hsi_port_unregister_clients(struct hsi_port *port) +{ + device_for_each_child(&port->device, NULL, hsi_remove_client); +} +EXPORT_SYMBOL_GPL(hsi_port_unregister_clients); + +/** + * hsi_unregister_controller - Unregister an HSI controller + * @hsi: The HSI controller to register + */ +void hsi_unregister_controller(struct hsi_controller *hsi) +{ + device_for_each_child(&hsi->device, NULL, hsi_remove_port); + device_unregister(&hsi->device); +} +EXPORT_SYMBOL_GPL(hsi_unregister_controller); + +/** + * hsi_register_controller - Register an HSI controller and its ports + * @hsi: The HSI controller to register + * + * Returns -errno on failure, 0 on success. + */ +int hsi_register_controller(struct hsi_controller *hsi) +{ + unsigned int i; + int err; + + err = device_add(&hsi->device); + if (err < 0) + return err; + for (i = 0; i < hsi->num_ports; i++) { + hsi->port[i]->device.parent = &hsi->device; + err = device_add(&hsi->port[i]->device); + if (err < 0) + goto out; + } + /* Populate HSI bus with HSI clients */ + hsi_scan_board_info(hsi); + + return 0; +out: + while (i-- > 0) + device_del(&hsi->port[i]->device); + device_del(&hsi->device); + + return err; +} +EXPORT_SYMBOL_GPL(hsi_register_controller); + +/** + * hsi_register_client_driver - Register an HSI client to the HSI bus + * @drv: HSI client driver to register + * + * Returns -errno on failure, 0 on success. + */ +int hsi_register_client_driver(struct hsi_client_driver *drv) +{ + drv->driver.bus = &hsi_bus_type; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL_GPL(hsi_register_client_driver); + +static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused) +{ + return 0; +} + +static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused) +{ + return 0; +} + +/** + * hsi_put_controller - Free an HSI controller + * + * @hsi: Pointer to the HSI controller to freed + * + * HSI controller drivers should only use this function if they need + * to free their allocated hsi_controller structures before a successful + * call to hsi_register_controller. Other use is not allowed. + */ +void hsi_put_controller(struct hsi_controller *hsi) +{ + unsigned int i; + + if (!hsi) + return; + + for (i = 0; i < hsi->num_ports; i++) + if (hsi->port && hsi->port[i]) + put_device(&hsi->port[i]->device); + put_device(&hsi->device); +} +EXPORT_SYMBOL_GPL(hsi_put_controller); + +/** + * hsi_alloc_controller - Allocate an HSI controller and its ports + * @n_ports: Number of ports on the HSI controller + * @flags: Kernel allocation flags + * + * Return NULL on failure or a pointer to an hsi_controller on success. + */ +struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) +{ + struct hsi_controller *hsi; + struct hsi_port **port; + unsigned int i; + + if (!n_ports) + return NULL; + + hsi = kzalloc(sizeof(*hsi), flags); + if (!hsi) + return NULL; + port = kzalloc(sizeof(*port)*n_ports, flags); + if (!port) { + kfree(hsi); + return NULL; + } + hsi->num_ports = n_ports; + hsi->port = port; + hsi->device.release = hsi_controller_release; + device_initialize(&hsi->device); + + for (i = 0; i < n_ports; i++) { + port[i] = kzalloc(sizeof(**port), flags); + if (port[i] == NULL) + goto out; + port[i]->num = i; + port[i]->async = hsi_dummy_msg; + port[i]->setup = hsi_dummy_cl; + port[i]->flush = hsi_dummy_cl; + port[i]->start_tx = hsi_dummy_cl; + port[i]->stop_tx = hsi_dummy_cl; + port[i]->release = hsi_dummy_cl; + mutex_init(&port[i]->lock); + ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); + dev_set_name(&port[i]->device, "port%d", i); + hsi->port[i]->device.release = hsi_port_release; + device_initialize(&hsi->port[i]->device); + } + + return hsi; +out: + hsi_put_controller(hsi); + + return NULL; +} +EXPORT_SYMBOL_GPL(hsi_alloc_controller); + +/** + * hsi_free_msg - Free an HSI message + * @msg: Pointer to the HSI message + * + * Client is responsible to free the buffers pointed by the scatterlists. + */ +void hsi_free_msg(struct hsi_msg *msg) +{ + if (!msg) + return; + sg_free_table(&msg->sgt); + kfree(msg); +} +EXPORT_SYMBOL_GPL(hsi_free_msg); + +/** + * hsi_alloc_msg - Allocate an HSI message + * @nents: Number of memory entries + * @flags: Kernel allocation flags + * + * nents can be 0. This mainly makes sense for read transfer. + * In that case, HSI drivers will call the complete callback when + * there is data to be read without consuming it. + * + * Return NULL on failure or a pointer to an hsi_msg on success. + */ +struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags) +{ + struct hsi_msg *msg; + int err; + + msg = kzalloc(sizeof(*msg), flags); + if (!msg) + return NULL; + + if (!nents) + return msg; + + err = sg_alloc_table(&msg->sgt, nents, flags); + if (unlikely(err)) { + kfree(msg); + msg = NULL; + } + + return msg; +} +EXPORT_SYMBOL_GPL(hsi_alloc_msg); + +/** + * hsi_async - Submit an HSI transfer to the controller + * @cl: HSI client sending the transfer + * @msg: The HSI transfer passed to controller + * + * The HSI message must have the channel, ttype, complete and destructor + * fields set beforehand. If nents > 0 then the client has to initialize + * also the scatterlists to point to the buffers to write to or read from. + * + * HSI controllers relay on pre-allocated buffers from their clients and they + * do not allocate buffers on their own. + * + * Once the HSI message transfer finishes, the HSI controller calls the + * complete callback with the status and actual_len fields of the HSI message + * updated. The complete callback can be called before returning from + * hsi_async. + * + * Returns -errno on failure or 0 on success + */ +int hsi_async(struct hsi_client *cl, struct hsi_msg *msg) +{ + struct hsi_port *port = hsi_get_port(cl); + + if (!hsi_port_claimed(cl)) + return -EACCES; + + WARN_ON_ONCE(!msg->destructor || !msg->complete); + msg->cl = cl; + + return port->async(msg); +} +EXPORT_SYMBOL_GPL(hsi_async); + +/** + * hsi_claim_port - Claim the HSI client's port + * @cl: HSI client that wants to claim its port + * @share: Flag to indicate if the client wants to share the port or not. + * + * Returns -errno on failure, 0 on success. + */ +int hsi_claim_port(struct hsi_client *cl, unsigned int share) +{ + struct hsi_port *port = hsi_get_port(cl); + int err = 0; + + mutex_lock(&port->lock); + if ((port->claimed) && (!port->shared || !share)) { + err = -EBUSY; + goto out; + } + if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) { + err = -ENODEV; + goto out; + } + port->claimed++; + port->shared = !!share; + cl->pclaimed = 1; +out: + mutex_unlock(&port->lock); + + return err; +} +EXPORT_SYMBOL_GPL(hsi_claim_port); + +/** + * hsi_release_port - Release the HSI client's port + * @cl: HSI client which previously claimed its port + */ +void hsi_release_port(struct hsi_client *cl) +{ + struct hsi_port *port = hsi_get_port(cl); + + mutex_lock(&port->lock); + /* Allow HW driver to do some cleanup */ + port->release(cl); + if (cl->pclaimed) + port->claimed--; + BUG_ON(port->claimed < 0); + cl->pclaimed = 0; + if (!port->claimed) + port->shared = 0; + module_put(to_hsi_controller(port->device.parent)->owner); + mutex_unlock(&port->lock); +} +EXPORT_SYMBOL_GPL(hsi_release_port); + +static int hsi_event_notifier_call(struct notifier_block *nb, + unsigned long event, void *data __maybe_unused) +{ + struct hsi_client *cl = container_of(nb, struct hsi_client, nb); + + (*cl->ehandler)(cl, event); + + return 0; +} + +/** + * hsi_register_port_event - Register a client to receive port events + * @cl: HSI client that wants to receive port events + * @handler: Event handler callback + * + * Clients should register a callback to be able to receive + * events from the ports. Registration should happen after + * claiming the port. + * The handler can be called in interrupt context. + * + * Returns -errno on error, or 0 on success. + */ +int hsi_register_port_event(struct hsi_client *cl, + void (*handler)(struct hsi_client *, unsigned long)) +{ + struct hsi_port *port = hsi_get_port(cl); + + if (!handler || cl->ehandler) + return -EINVAL; + if (!hsi_port_claimed(cl)) + return -EACCES; + cl->ehandler = handler; + cl->nb.notifier_call = hsi_event_notifier_call; + + return atomic_notifier_chain_register(&port->n_head, &cl->nb); +} +EXPORT_SYMBOL_GPL(hsi_register_port_event); + +/** + * hsi_unregister_port_event - Stop receiving port events for a client + * @cl: HSI client that wants to stop receiving port events + * + * Clients should call this function before releasing their associated + * port. + * + * Returns -errno on error, or 0 on success. + */ +int hsi_unregister_port_event(struct hsi_client *cl) +{ + struct hsi_port *port = hsi_get_port(cl); + int err; + + WARN_ON(!hsi_port_claimed(cl)); + + err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); + if (!err) + cl->ehandler = NULL; + + return err; +} +EXPORT_SYMBOL_GPL(hsi_unregister_port_event); + +/** + * hsi_event - Notifies clients about port events + * @port: Port where the event occurred + * @event: The event type + * + * Clients should not be concerned about wake line behavior. However, due + * to a race condition in HSI HW protocol, clients need to be notified + * about wake line changes, so they can implement a workaround for it. + * + * Events: + * HSI_EVENT_START_RX - Incoming wake line high + * HSI_EVENT_STOP_RX - Incoming wake line down + * + * Returns -errno on error, or 0 on success. + */ +int hsi_event(struct hsi_port *port, unsigned long event) +{ + return atomic_notifier_call_chain(&port->n_head, event, NULL); +} +EXPORT_SYMBOL_GPL(hsi_event); + +/** + * hsi_get_channel_id_by_name - acquire channel id by channel name + * @cl: HSI client, which uses the channel + * @name: name the channel is known under + * + * Clients can call this function to get the hsi channel ids similar to + * requesting IRQs or GPIOs by name. This function assumes the same + * channel configuration is used for RX and TX. + * + * Returns -errno on error or channel id on success. + */ +int hsi_get_channel_id_by_name(struct hsi_client *cl, char *name) +{ + int i; + + if (!cl->rx_cfg.channels) + return -ENOENT; + + for (i = 0; i < cl->rx_cfg.num_channels; i++) + if (!strcmp(cl->rx_cfg.channels[i].name, name)) + return cl->rx_cfg.channels[i].id; + + return -ENXIO; +} +EXPORT_SYMBOL_GPL(hsi_get_channel_id_by_name); + +static int __init hsi_init(void) +{ + return bus_register(&hsi_bus_type); +} +postcore_initcall(hsi_init); + +static void __exit hsi_exit(void) +{ + bus_unregister(&hsi_bus_type); +} +module_exit(hsi_exit); + +MODULE_AUTHOR("Carlos Chinea "); +MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework"); +MODULE_LICENSE("GPL v2"); -- cgit v1.3-14-g43fede From ee6ea993dfb27c4a809c3384b19b58eebea65a36 Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Mon, 7 Mar 2016 10:44:54 +0000 Subject: dt/bindings: display: Add DT bindings for Mali Display Processors. Add DT bindings documentation for the Mali Display Processor. The bindings describe the Mali DP500, DP550 and DP650 processors from ARM Ltd. Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Signed-off-by: Liviu Dudau Acked-by: Rob Herring --- .../devicetree/bindings/display/arm,malidp.txt | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/arm,malidp.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/arm,malidp.txt b/Documentation/devicetree/bindings/display/arm,malidp.txt new file mode 100644 index 000000000000..2f7870983ef1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,malidp.txt @@ -0,0 +1,65 @@ +ARM Mali-DP + +The following bindings apply to a family of Display Processors sold as +licensable IP by ARM Ltd. The bindings describe the Mali DP500, DP550 and +DP650 processors that offer multiple composition layers, support for +rotation and scaling output. + +Required properties: + - compatible: should be one of + "arm,mali-dp500" + "arm,mali-dp550" + "arm,mali-dp650" + depending on the particular implementation present in the hardware + - reg: Physical base address and size of the block of registers used by + the processor. + - interrupts: Interrupt list, as defined in ../interrupt-controller/interrupts.txt, + interrupt client nodes. + - interrupt-names: name of the engine inside the processor that will + use the corresponding interrupt. Should be one of "DE" or "SE". + - clocks: A list of phandle + clock-specifier pairs, one for each entry + in 'clock-names' + - clock-names: A list of clock names. It should contain: + - "pclk": for the APB interface clock + - "aclk": for the AXI interface clock + - "mclk": for the main processor clock + - "pxlclk": for the pixel clock feeding the output PLL of the processor. + - arm,malidp-output-port-lines: Array of u8 values describing the number + of output lines per channel (R, G and B). + +Required sub-nodes: + - port: The Mali DP connection to an encoder input port. The connection + is modelled using the OF graph bindings specified in + Documentation/devicetree/bindings/graph.txt + +Optional properties: + - memory-region: phandle to a node describing memory (see + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) + to be used for the framebuffer; if not present, the framebuffer may + be located anywhere in memory. + + +Example: + +/ { + ... + + dp0: malidp@6f200000 { + compatible = "arm,mali-dp650"; + reg = <0 0x6f200000 0 0x20000>; + memory-region = <&display_reserved>; + interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>, + <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "DE", "SE"; + clocks = <&oscclk2>, <&fpgaosc0>, <&fpgaosc1>, <&fpgaosc1>; + clock-names = "pxlclk", "mclk", "aclk", "pclk"; + arm,malidp-output-port-lines = /bits/ 8 <8 8 8>; + port { + dp0_output: endpoint { + remote-endpoint = <&tda998x_2_input>; + }; + }; + }; + + ... +}; -- cgit v1.3-14-g43fede From b1ec5b5a93dac0b301a54706573348ed7d9bd7f6 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2016 12:01:45 +0200 Subject: dt-bindings: hwrng: Add Amlogic Meson Hardware Random Generator bindings Acked-by: Rob Herring Signed-off-by: Neil Armstrong Signed-off-by: Kevin Hilman --- .../devicetree/bindings/rng/amlogic,meson-rng.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt b/Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt new file mode 100644 index 000000000000..202f2d09a23f --- /dev/null +++ b/Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt @@ -0,0 +1,14 @@ +Amlogic Meson Random number generator +===================================== + +Required properties: + +- compatible : should be "amlogic,meson-rng" +- reg : Specifies base physical address and size of the registers. + +Example: + +rng { + compatible = "amlogic,meson-rng"; + reg = <0x0 0xc8834000 0x0 0x4>; +}; -- cgit v1.3-14-g43fede From 818d49ad164cb680983568e3307a30012ab66a23 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 13 Jun 2016 18:52:17 +0300 Subject: dt: bindings: Add bindings for Cirrus Logic CS89x0 ethernet chip Add device tree binding documentation details for Cirrus Logic CS8900/CS8920 ethernet chip. Signed-off-by: Alexander Shiyan Acked-by: Rob Herring Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/cirrus,cs89x0.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/cirrus,cs89x0.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/cirrus,cs89x0.txt b/Documentation/devicetree/bindings/net/cirrus,cs89x0.txt new file mode 100644 index 000000000000..c070076bacb9 --- /dev/null +++ b/Documentation/devicetree/bindings/net/cirrus,cs89x0.txt @@ -0,0 +1,13 @@ +* Cirrus Logic CS8900/CS8920 Network Controller + +Required properties: +- compatible : Should be "cirrus,cs8900" or "cirrus,cs8920". +- reg : Address and length of the IO space. +- interrupts : Should contain the controller interrupt line. + +Examples: + eth0: eth@10000000 { + compatible = "cirrus,cs8900"; + reg = <0x10000000 0x400>; + interrupts = <10>; + }; -- cgit v1.3-14-g43fede From 05108709526716e1d40210fe3b9d7acd1cb694ea Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 15 Jun 2016 19:29:56 +0100 Subject: MIPS: KVM: Add KScratch registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow up to 6 KVM guest KScratch registers to be enabled and accessed via the KVM guest register API and from the guest itself (the fallback reading and writing of commpage registers is sufficient for KScratch registers to work as expected). User mode can expose the registers by setting the appropriate bits of the guest Config4.KScrExist field. KScratch registers that aren't usable won't be writeable via the KVM Ioctl API. Signed-off-by: James Hogan Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Signed-off-by: Paolo Bonzini --- Documentation/virtual/kvm/api.txt | 6 ++++ arch/mips/include/asm/kvm_host.h | 19 +++++++++++ arch/mips/kvm/emulate.c | 7 +++- arch/mips/kvm/mips.c | 71 +++++++++++++++++++++++++++++++++++++++ arch/mips/kvm/trace.h | 6 ++++ arch/mips/kvm/trap_emul.c | 2 ++ 6 files changed, 110 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 4aac3e51bf9f..09efa9eb3926 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2032,6 +2032,12 @@ registers, find a list below: MIPS | KVM_REG_MIPS_CP0_CONFIG5 | 32 MIPS | KVM_REG_MIPS_CP0_CONFIG7 | 32 MIPS | KVM_REG_MIPS_CP0_ERROREPC | 64 + MIPS | KVM_REG_MIPS_CP0_KSCRATCH1 | 64 + MIPS | KVM_REG_MIPS_CP0_KSCRATCH2 | 64 + MIPS | KVM_REG_MIPS_CP0_KSCRATCH3 | 64 + MIPS | KVM_REG_MIPS_CP0_KSCRATCH4 | 64 + MIPS | KVM_REG_MIPS_CP0_KSCRATCH5 | 64 + MIPS | KVM_REG_MIPS_CP0_KSCRATCH6 | 64 MIPS | KVM_REG_MIPS_COUNT_CTL | 64 MIPS | KVM_REG_MIPS_COUNT_RESUME | 64 MIPS | KVM_REG_MIPS_COUNT_HZ | 64 diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index f12eb01a3195..5e9da2a31fde 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -56,6 +56,12 @@ #define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) #define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) +#define KVM_REG_MIPS_CP0_KSCRATCH1 MIPS_CP0_64(31, 2) +#define KVM_REG_MIPS_CP0_KSCRATCH2 MIPS_CP0_64(31, 3) +#define KVM_REG_MIPS_CP0_KSCRATCH3 MIPS_CP0_64(31, 4) +#define KVM_REG_MIPS_CP0_KSCRATCH4 MIPS_CP0_64(31, 5) +#define KVM_REG_MIPS_CP0_KSCRATCH5 MIPS_CP0_64(31, 6) +#define KVM_REG_MIPS_CP0_KSCRATCH6 MIPS_CP0_64(31, 7) #define KVM_MAX_VCPUS 1 @@ -376,6 +382,7 @@ struct kvm_vcpu_arch { u8 fpu_enabled; u8 msa_enabled; + u8 kscratch_enabled; }; @@ -429,6 +436,18 @@ struct kvm_vcpu_arch { #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) +#define kvm_read_c0_guest_kscratch1(cop0) (cop0->reg[MIPS_CP0_DESAVE][2]) +#define kvm_read_c0_guest_kscratch2(cop0) (cop0->reg[MIPS_CP0_DESAVE][3]) +#define kvm_read_c0_guest_kscratch3(cop0) (cop0->reg[MIPS_CP0_DESAVE][4]) +#define kvm_read_c0_guest_kscratch4(cop0) (cop0->reg[MIPS_CP0_DESAVE][5]) +#define kvm_read_c0_guest_kscratch5(cop0) (cop0->reg[MIPS_CP0_DESAVE][6]) +#define kvm_read_c0_guest_kscratch6(cop0) (cop0->reg[MIPS_CP0_DESAVE][7]) +#define kvm_write_c0_guest_kscratch1(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][2] = (val)) +#define kvm_write_c0_guest_kscratch2(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][3] = (val)) +#define kvm_write_c0_guest_kscratch3(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][4] = (val)) +#define kvm_write_c0_guest_kscratch4(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][5] = (val)) +#define kvm_write_c0_guest_kscratch5(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][6] = (val)) +#define kvm_write_c0_guest_kscratch6(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][7] = (val)) /* * Some of the guest registers may be modified asynchronously (e.g. from a diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 4ca5450febbb..5f0354c80c8e 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c @@ -941,7 +941,12 @@ unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu) unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu) { /* Config5 is optional */ - return MIPS_CONF_M; + unsigned int mask = MIPS_CONF_M; + + /* KScrExist */ + mask |= (unsigned int)vcpu->arch.kscratch_enabled << 16; + + return mask; } /** diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 622b9feba927..5a2b9034a05c 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -9,6 +9,7 @@ * Authors: Sanjay Lal */ +#include #include #include #include @@ -548,6 +549,15 @@ static u64 kvm_mips_get_one_regs_msa[] = { KVM_REG_MIPS_MSA_CSR, }; +static u64 kvm_mips_get_one_regs_kscratch[] = { + KVM_REG_MIPS_CP0_KSCRATCH1, + KVM_REG_MIPS_CP0_KSCRATCH2, + KVM_REG_MIPS_CP0_KSCRATCH3, + KVM_REG_MIPS_CP0_KSCRATCH4, + KVM_REG_MIPS_CP0_KSCRATCH5, + KVM_REG_MIPS_CP0_KSCRATCH6, +}; + static unsigned long kvm_mips_num_regs(struct kvm_vcpu *vcpu) { unsigned long ret; @@ -561,6 +571,7 @@ static unsigned long kvm_mips_num_regs(struct kvm_vcpu *vcpu) } if (kvm_mips_guest_can_have_msa(&vcpu->arch)) ret += ARRAY_SIZE(kvm_mips_get_one_regs_msa) + 32; + ret += __arch_hweight8(vcpu->arch.kscratch_enabled); ret += kvm_mips_callbacks->num_regs(vcpu); return ret; @@ -613,6 +624,16 @@ static int kvm_mips_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices) } } + for (i = 0; i < 6; ++i) { + if (!(vcpu->arch.kscratch_enabled & BIT(i + 2))) + continue; + + if (copy_to_user(indices, &kvm_mips_get_one_regs_kscratch[i], + sizeof(kvm_mips_get_one_regs_kscratch[i]))) + return -EFAULT; + ++indices; + } + return kvm_mips_callbacks->copy_reg_indices(vcpu, indices); } @@ -765,6 +786,31 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, case KVM_REG_MIPS_CP0_ERROREPC: v = (long)kvm_read_c0_guest_errorepc(cop0); break; + case KVM_REG_MIPS_CP0_KSCRATCH1 ... KVM_REG_MIPS_CP0_KSCRATCH6: + idx = reg->id - KVM_REG_MIPS_CP0_KSCRATCH1 + 2; + if (!(vcpu->arch.kscratch_enabled & BIT(idx))) + return -EINVAL; + switch (idx) { + case 2: + v = (long)kvm_read_c0_guest_kscratch1(cop0); + break; + case 3: + v = (long)kvm_read_c0_guest_kscratch2(cop0); + break; + case 4: + v = (long)kvm_read_c0_guest_kscratch3(cop0); + break; + case 5: + v = (long)kvm_read_c0_guest_kscratch4(cop0); + break; + case 6: + v = (long)kvm_read_c0_guest_kscratch5(cop0); + break; + case 7: + v = (long)kvm_read_c0_guest_kscratch6(cop0); + break; + } + break; /* registers to be handled specially */ default: ret = kvm_mips_callbacks->get_one_reg(vcpu, reg, &v); @@ -931,6 +977,31 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, case KVM_REG_MIPS_CP0_ERROREPC: kvm_write_c0_guest_errorepc(cop0, v); break; + case KVM_REG_MIPS_CP0_KSCRATCH1 ... KVM_REG_MIPS_CP0_KSCRATCH6: + idx = reg->id - KVM_REG_MIPS_CP0_KSCRATCH1 + 2; + if (!(vcpu->arch.kscratch_enabled & BIT(idx))) + return -EINVAL; + switch (idx) { + case 2: + kvm_write_c0_guest_kscratch1(cop0, v); + break; + case 3: + kvm_write_c0_guest_kscratch2(cop0, v); + break; + case 4: + kvm_write_c0_guest_kscratch3(cop0, v); + break; + case 5: + kvm_write_c0_guest_kscratch4(cop0, v); + break; + case 6: + kvm_write_c0_guest_kscratch5(cop0, v); + break; + case 7: + kvm_write_c0_guest_kscratch6(cop0, v); + break; + } + break; /* registers to be handled specially */ default: return kvm_mips_callbacks->set_one_reg(vcpu, reg, v); diff --git a/arch/mips/kvm/trace.h b/arch/mips/kvm/trace.h index 5d712ecb0734..a38bdab68574 100644 --- a/arch/mips/kvm/trace.h +++ b/arch/mips/kvm/trace.h @@ -178,6 +178,12 @@ TRACE_EVENT(kvm_exit, { KVM_TRACE_COP0(16, 7), "Config7" }, \ { KVM_TRACE_COP0(26, 0), "ECC" }, \ { KVM_TRACE_COP0(30, 0), "ErrorEPC" }, \ + { KVM_TRACE_COP0(31, 2), "KScratch1" }, \ + { KVM_TRACE_COP0(31, 3), "KScratch2" }, \ + { KVM_TRACE_COP0(31, 4), "KScratch3" }, \ + { KVM_TRACE_COP0(31, 5), "KScratch4" }, \ + { KVM_TRACE_COP0(31, 6), "KScratch5" }, \ + { KVM_TRACE_COP0(31, 7), "KScratch6" }, \ { KVM_TRACE_HWR( 0, 0), "CPUNum" }, \ { KVM_TRACE_HWR( 1, 0), "SYNCI_Step" }, \ { KVM_TRACE_HWR( 2, 0), "CC" }, \ diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index b64ca1a222f7..eb191c4612bb 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c @@ -418,6 +418,8 @@ static int kvm_trap_emul_vm_init(struct kvm *kvm) static int kvm_trap_emul_vcpu_init(struct kvm_vcpu *vcpu) { + vcpu->arch.kscratch_enabled = 0xfc; + return 0; } -- cgit v1.3-14-g43fede From 088e9d253d3a4ab7e058dd84bb532c32dadf1882 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Thu, 2 Jun 2016 13:51:41 -0300 Subject: rcu: sysctl: Panic on RCU Stall It is not always easy to determine the cause of an RCU stall just by analysing the RCU stall messages, mainly when the problem is caused by the indirect starvation of rcu threads. For example, when preempt_rcu is not awakened due to the starvation of a timer softirq. We have been hard coding panic() in the RCU stall functions for some time while testing the kernel-rt. But this is not possible in some scenarios, like when supporting customers. This patch implements the sysctl kernel.panic_on_rcu_stall. If set to 1, the system will panic() when an RCU stall takes place, enabling the capture of a vmcore. The vmcore provides a way to analyze all kernel/tasks states, helping out to point to the culprit and the solution for the stall. The kernel.panic_on_rcu_stall sysctl is disabled by default. Changes from v1: - Fixed a typo in the git log - The if(sysctl_panic_on_rcu_stall) panic() is in a static function - Fixed the CONFIG_TINY_RCU compilation issue - The var sysctl_panic_on_rcu_stall is now __read_mostly Cc: Jonathan Corbet Cc: "Paul E. McKenney" Cc: Josh Triplett Cc: Steven Rostedt Cc: Mathieu Desnoyers Cc: Lai Jiangshan Acked-by: Christian Borntraeger Reviewed-by: Josh Triplett Reviewed-by: Arnaldo Carvalho de Melo Tested-by: "Luis Claudio R. Goncalves" Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Paul E. McKenney --- Documentation/sysctl/kernel.txt | 12 ++++++++++++ include/linux/kernel.h | 1 + kernel/rcu/tree.c | 12 ++++++++++++ kernel/sysctl.c | 11 +++++++++++ 4 files changed, 36 insertions(+) (limited to 'Documentation') diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index a3683ce2a2f3..33204604de6c 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -58,6 +58,7 @@ show up in /proc/sys/kernel: - panic_on_stackoverflow - panic_on_unrecovered_nmi - panic_on_warn +- panic_on_rcu_stall - perf_cpu_time_max_percent - perf_event_paranoid - perf_event_max_stack @@ -618,6 +619,17 @@ a kernel rebuild when attempting to kdump at the location of a WARN(). ============================================================== +panic_on_rcu_stall: + +When set to 1, calls panic() after RCU stall detection messages. This +is useful to define the root cause of RCU stalls using a vmcore. + +0: do not panic() when RCU stall takes place, default behavior. + +1: panic() after printing RCU stall messages. + +============================================================== + perf_cpu_time_max_percent: Hints to the kernel how much CPU time it should be allowed to diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94aa10ffe156..c42082112ec8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -451,6 +451,7 @@ extern int panic_on_oops; extern int panic_on_unrecovered_nmi; extern int panic_on_io_nmi; extern int panic_on_warn; +extern int sysctl_panic_on_rcu_stall; extern int sysctl_panic_on_stackoverflow; extern bool crash_kexec_post_notifiers; diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index c844b6142a86..e5ca15a461b9 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -125,6 +125,8 @@ int rcu_num_lvls __read_mostly = RCU_NUM_LVLS; /* Number of rcu_nodes at specified level. */ static int num_rcu_lvl[] = NUM_RCU_LVL_INIT; int rcu_num_nodes __read_mostly = NUM_RCU_NODES; /* Total # rcu_nodes in use. */ +/* panic() on RCU Stall sysctl. */ +int sysctl_panic_on_rcu_stall __read_mostly; /* * The rcu_scheduler_active variable transitions from zero to one just @@ -1312,6 +1314,12 @@ static void rcu_stall_kick_kthreads(struct rcu_state *rsp) } } +static inline void panic_on_rcu_stall(void) +{ + if (sysctl_panic_on_rcu_stall) + panic("RCU Stall\n"); +} + static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum) { int cpu; @@ -1391,6 +1399,8 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum) rcu_check_gp_kthread_starvation(rsp); + panic_on_rcu_stall(); + force_quiescent_state(rsp); /* Kick them all. */ } @@ -1431,6 +1441,8 @@ static void print_cpu_stall(struct rcu_state *rsp) jiffies + 3 * rcu_jiffies_till_stall_check() + 3); raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + panic_on_rcu_stall(); + /* * Attempt to revive the RCU machinery by forcing a context switch. * diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 87b2fc38398b..35f0dcb1cb4f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1204,6 +1204,17 @@ static struct ctl_table kern_table[] = { .extra1 = &one, .extra2 = &one, }, +#endif +#if defined(CONFIG_TREE_RCU) || defined(CONFIG_PREEMPT_RCU) + { + .procname = "panic_on_rcu_stall", + .data = &sysctl_panic_on_rcu_stall, + .maxlen = sizeof(sysctl_panic_on_rcu_stall), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, + }, #endif { } }; -- cgit v1.3-14-g43fede From 6bc734c64631d21fd4d95a25cc3c1283ac721bb8 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 13 Jun 2016 00:14:01 +0300 Subject: ARM: dts: blanche: document Blanche board Document the Blanche device tree bindings, listing it as a supported board. This allows to use checkpatch.pl to validate .dts files referring to the Blanche board. Signed-off-by: Sergei Shtylyov Acked-by: Rob Herring Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/arm/shmobile.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 9cf67e48f222..6adb9d549fce 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -39,6 +39,8 @@ Boards: compatible = "renesas,ape6evm", "renesas,r8a73a4" - Atmark Techno Armadillo-800 EVA compatible = "renesas,armadillo800eva" + - Blanche (RTP0RC7792SEB00010S) + compatible = "renesas,blanche", "renesas,r8a7792" - BOCK-W compatible = "renesas,bockw", "renesas,r8a7778" - Genmai (RTK772100BC00000BR) -- cgit v1.3-14-g43fede From 2f082b13f2ef89548d5629d9bbf8795ed246a0ec Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Tue, 7 Jun 2016 14:55:45 +0800 Subject: bindings: PCI: layerscape: Add 'dma-coherent' property Add 'dma-coherent' description for PCI nodes. The 'dma-coherent' indicates that the hardware IP block can ensure the coherency of the data transferred from/to the IP block. This can avoid the software cache flush/invalid actions, and improve the performance significantly. The PCI IP block of ls1043a has this capability, so adding this feature to improve the PCI performance. Signed-off-by: Liu Gang Acked-by: Rob Herring Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/pci/layerscape-pci.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index ef683b2fd23a..41e9f55a1467 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -24,6 +24,9 @@ Required properties: The first entry must be a link to the SCFG device node The second entry must be '0' or '1' based on physical PCIe controller index. This is used to get SCFG PEXN registers +- dma-coherent: Indicates that the hardware IP block can ensure the coherency + of the data transferred from/to the IP block. This can avoid the software + cache flush/invalid actions, and improve the performance significantly. Example: @@ -38,6 +41,7 @@ Example: #address-cells = <3>; #size-cells = <2>; device_type = "pci"; + dma-coherent; num-lanes = <4>; bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ -- cgit v1.3-14-g43fede From 9a449e0de0d708bae7af7f897c1a67848f91c455 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 4 Nov 2015 12:45:09 +0100 Subject: dt-bindings: hdmi-connector: add DDC I2C bus phandle documentation Add an optional ddc-i2c-bus phandle property that points to an I2C master controller that handles the connector DDC pins. Signed-off-by: Philipp Zabel Acked-by: Rob Herring --- Documentation/devicetree/bindings/display/connector/hdmi-connector.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/connector/hdmi-connector.txt b/Documentation/devicetree/bindings/display/connector/hdmi-connector.txt index acd5668b1ce1..508aee461e0d 100644 --- a/Documentation/devicetree/bindings/display/connector/hdmi-connector.txt +++ b/Documentation/devicetree/bindings/display/connector/hdmi-connector.txt @@ -8,6 +8,7 @@ Required properties: Optional properties: - label: a symbolic name for the connector - hpd-gpios: HPD GPIO number +- ddc-i2c-bus: phandle link to the I2C controller used for DDC EDID probing Required nodes: - Video port for HDMI input -- cgit v1.3-14-g43fede From 7a4f9830f04c8450a486eb1faf401596259d821b Mon Sep 17 00:00:00 2001 From: Chris Brand Date: Wed, 8 Jun 2016 12:16:44 -0700 Subject: docs: Move brcm,bcm21664-resetmgr.txt Sebastian pointed out that .../bindings/reset is usually used for peripheral reset controllers, whereas .../bindings/power/reset is used for Board/System reset controllers. Reported-by: Sebastian Reichel Signed-off-by: Chris Brand Signed-off-by: Sebastian Reichel --- .../bindings/power/reset/brcm,bcm21664-resetmgr.txt | 14 ++++++++++++++ .../devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt | 14 -------------- 2 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt delete mode 100644 Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt b/Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt new file mode 100644 index 000000000000..93f31ca1ef4b --- /dev/null +++ b/Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt @@ -0,0 +1,14 @@ +Broadcom Kona Family Reset Manager +---------------------------------- + +The reset manager is used on the Broadcom BCM21664 SoC. + +Required properties: + - compatible: brcm,bcm21664-resetmgr + - reg: memory address & range + +Example: + brcm,resetmgr@35001f00 { + compatible = "brcm,bcm21664-resetmgr"; + reg = <0x35001f00 0x24>; + }; diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt b/Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt deleted file mode 100644 index 93f31ca1ef4b..000000000000 --- a/Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt +++ /dev/null @@ -1,14 +0,0 @@ -Broadcom Kona Family Reset Manager ----------------------------------- - -The reset manager is used on the Broadcom BCM21664 SoC. - -Required properties: - - compatible: brcm,bcm21664-resetmgr - - reg: memory address & range - -Example: - brcm,resetmgr@35001f00 { - compatible = "brcm,bcm21664-resetmgr"; - reg = <0x35001f00 0x24>; - }; -- cgit v1.3-14-g43fede From dc5a78ec8efb74964b77982b2ea79434ed8941e5 Mon Sep 17 00:00:00 2001 From: Yendapally Reddy Dhananjaya Reddy Date: Thu, 16 Jun 2016 09:53:29 -0400 Subject: dt-bindings: ata: rename brcm, sata-brcmstb.txt to brcm, sata-brcm.txt Renames the dt bindings document of Broadcom STB ahci driver to common Broadcom ahci driver bindings document Signed-off-by: Yendapally Reddy Dhananjaya Reddy Acked-by: Florian Fainelli Signed-off-by: Tejun Heo --- .../devicetree/bindings/ata/brcm,sata-brcm.txt | 36 ++++++++++++++++++++++ .../devicetree/bindings/ata/brcm,sata-brcmstb.txt | 36 ---------------------- 2 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt delete mode 100644 Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt b/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt new file mode 100644 index 000000000000..126ee137d054 --- /dev/null +++ b/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt @@ -0,0 +1,36 @@ +* Broadcom SATA3 AHCI Controller + +SATA nodes are defined to describe on-chip Serial ATA controllers. +Each SATA controller should have its own node. + +Required properties: +- compatible : should be one or more of + "brcm,bcm7425-ahci" + "brcm,bcm7445-ahci" + "brcm,sata3-ahci" +- reg : register mappings for AHCI and SATA_TOP_CTRL +- reg-names : "ahci" and "top-ctrl" +- interrupts : interrupt mapping for SATA IRQ + +Also see ahci-platform.txt. + +Example: + + sata@f045a000 { + compatible = "brcm,bcm7445-ahci", "brcm,sata3-ahci"; + reg = <0xf045a000 0xa9c>, <0xf0458040 0x24>; + reg-names = "ahci", "top-ctrl"; + interrupts = <0 30 0>; + #address-cells = <1>; + #size-cells = <0>; + + sata0: sata-port@0 { + reg = <0>; + phys = <&sata_phy 0>; + }; + + sata1: sata-port@1 { + reg = <1>; + phys = <&sata_phy 1>; + }; + }; diff --git a/Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt b/Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt deleted file mode 100644 index 60872838f1ad..000000000000 --- a/Documentation/devicetree/bindings/ata/brcm,sata-brcmstb.txt +++ /dev/null @@ -1,36 +0,0 @@ -* Broadcom SATA3 AHCI Controller for STB - -SATA nodes are defined to describe on-chip Serial ATA controllers. -Each SATA controller should have its own node. - -Required properties: -- compatible : should be one or more of - "brcm,bcm7425-ahci" - "brcm,bcm7445-ahci" - "brcm,sata3-ahci" -- reg : register mappings for AHCI and SATA_TOP_CTRL -- reg-names : "ahci" and "top-ctrl" -- interrupts : interrupt mapping for SATA IRQ - -Also see ahci-platform.txt. - -Example: - - sata@f045a000 { - compatible = "brcm,bcm7445-ahci", "brcm,sata3-ahci"; - reg = <0xf045a000 0xa9c>, <0xf0458040 0x24>; - reg-names = "ahci", "top-ctrl"; - interrupts = <0 30 0>; - #address-cells = <1>; - #size-cells = <0>; - - sata0: sata-port@0 { - reg = <0>; - phys = <&sata_phy 0>; - }; - - sata1: sata-port@1 { - reg = <1>; - phys = <&sata_phy 1>; - }; - }; -- cgit v1.3-14-g43fede From 5724ad14cc85513a55711d6b4d6142b8e188c7e2 Mon Sep 17 00:00:00 2001 From: Yendapally Reddy Dhananjaya Reddy Date: Thu, 16 Jun 2016 09:53:30 -0400 Subject: dt-bindings: ata: add support for Broadcom NSP SoC ahci Add support for Broadcom NSP SoC ahci Signed-off-by: Yendapally Reddy Dhananjaya Reddy Acked-by: Florian Fainelli Signed-off-by: Tejun Heo --- Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt b/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt index 126ee137d054..0a5b3b47f217 100644 --- a/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt +++ b/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt @@ -7,6 +7,7 @@ Required properties: - compatible : should be one or more of "brcm,bcm7425-ahci" "brcm,bcm7445-ahci" + "brcm,bcm-nsp-ahci" "brcm,sata3-ahci" - reg : register mappings for AHCI and SATA_TOP_CTRL - reg-names : "ahci" and "top-ctrl" -- cgit v1.3-14-g43fede From a55448d1c01ca4b4e94e1d51249feee4aa315d6d Mon Sep 17 00:00:00 2001 From: Yendapally Reddy Dhananjaya Reddy Date: Thu, 16 Jun 2016 09:53:31 -0400 Subject: dt-bindings: phy: Add documentation for NSP SATA PHY Add documentation for SATA PHY available in Broadcom's NSP SoC. Signed-off-by: Yendapally Reddy Dhananjaya Reddy Acked-by: Florian Fainelli Signed-off-by: Tejun Heo --- Documentation/devicetree/bindings/phy/brcm-sata-phy.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt index d0231209d846..6ccce09d8bbf 100644 --- a/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt +++ b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt @@ -5,6 +5,7 @@ Required properties: "brcm,bcm7425-sata-phy" "brcm,bcm7445-sata-phy" "brcm,iproc-ns2-sata-phy" + "brcm,iproc-nsp-sata-phy" "brcm,phy-sata3" - address-cells: should be 1 - size-cells: should be 0 @@ -22,7 +23,8 @@ Sub-nodes required properties: Sub-nodes optional properties: - brcm,enable-ssc: use spread spectrum clocking (SSC) on this port - This property is not applicable for "brcm,iproc-ns2-sata-phy". + This property is not applicable for "brcm,iproc-ns2-sata-phy" and + "brcm,iproc-nsp-sata-phy". Example: sata-phy@f0458100 { -- cgit v1.3-14-g43fede From ebff09a6ff164aec2b33bf1f9a488c45ac108413 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 15 Jun 2016 16:08:17 -0700 Subject: locking/Documentation: Clarify limited control-dependency scope Nothing in the control-dependencies section of memory-barriers.txt says that control dependencies don't extend beyond the end of the if-statement containing the control dependency. Worse yet, in many situations, they do extend beyond that if-statement. In particular, the compiler cannot destroy the control dependency given proper use of READ_ONCE() and WRITE_ONCE(). However, a weakly ordered system having a conditional-move instruction provides the control-dependency guarantee only to code within the scope of the if-statement itself. This commit therefore adds words and an example demonstrating this limitation of control dependencies. Reported-by: Will Deacon Signed-off-by: Paul E. McKenney Acked-by: Peter Zijlstra (Intel) Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: corbet@lwn.net Cc: linux-arch@vger.kernel.org Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20160615230817.GA18039@linux.vnet.ibm.com Signed-off-by: Ingo Molnar --- Documentation/memory-barriers.txt | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'Documentation') diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 147ae8ec836f..a4d0a99de04d 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -806,6 +806,41 @@ out-guess your code. More generally, although READ_ONCE() does force the compiler to actually emit code for a given load, it does not force the compiler to use the results. +In addition, control dependencies apply only to the then-clause and +else-clause of the if-statement in question. In particular, it does +not necessarily apply to code following the if-statement: + + q = READ_ONCE(a); + if (q) { + WRITE_ONCE(b, p); + } else { + WRITE_ONCE(b, r); + } + WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */ + +It is tempting to argue that there in fact is ordering because the +compiler cannot reorder volatile accesses and also cannot reorder +the writes to "b" with the condition. Unfortunately for this line +of reasoning, the compiler might compile the two writes to "b" as +conditional-move instructions, as in this fanciful pseudo-assembly +language: + + ld r1,a + ld r2,p + ld r3,r + cmp r1,$0 + cmov,ne r4,r2 + cmov,eq r4,r3 + st r4,b + st $1,c + +A weakly ordered CPU would have no dependency of any sort between the load +from "a" and the store to "c". The control dependencies would extend +only to the pair of cmov instructions and the store depending on them. +In short, control dependencies apply only to the stores in the then-clause +and else-clause of the if-statement in question (including functions +invoked by those two clauses), not to code following that if-statement. + Finally, control dependencies do -not- provide transitivity. This is demonstrated by two related examples, with the initial values of x and y both being zero: @@ -869,6 +904,12 @@ In summary: atomic{,64}_read() can help to preserve your control dependency. Please see the COMPILER BARRIER section for more information. + (*) Control dependencies apply only to the then-clause and else-clause + of the if-statement containing the control dependency, including + any functions that these two clauses call. Control dependencies + do -not- apply to code following the if-statement containing the + control dependency. + (*) Control dependencies pair normally with other types of barriers. (*) Control dependencies do -not- provide transitivity. If you -- cgit v1.3-14-g43fede From 60135db8d7acaff289d10568068469b57b730b6b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 23 Apr 2016 20:37:44 -0300 Subject: [media] dt-bindings: Add Renesas R-Car FCP DT bindings The FCP is a companion module of video processing modules in the Renesas R-Car Gen3 SoCs. It provides data compression and decompression, data caching, and conversion of AXI transactions in order to reduce the memory bandwidth. Signed-off-by: Laurent Pinchart Acked-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/renesas,fcp.txt | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/renesas,fcp.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt new file mode 100644 index 000000000000..6a12960609d8 --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt @@ -0,0 +1,32 @@ +Renesas R-Car Frame Compression Processor (FCP) +----------------------------------------------- + +The FCP is a companion module of video processing modules in the Renesas R-Car +Gen3 SoCs. It provides data compression and decompression, data caching, and +conversion of AXI transactions in order to reduce the memory bandwidth. + +There are three types of FCP: FCP for Codec (FCPC), FCP for VSP (FCPV) and FCP +for FDP (FCPF). Their configuration and behaviour depend on the module they +are paired with. These DT bindings currently support the FCPV only. + + - compatible: Must be one or more of the following + + - "renesas,r8a7795-fcpv" for R8A7795 (R-Car H3) compatible 'FCP for VSP' + - "renesas,fcpv" for generic compatible 'FCP for VSP' + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first, followed by the + family-specific and/or generic versions. + + - reg: the register base and size for the device registers + - clocks: Reference to the functional clock + + +Device node example +------------------- + + fcpvd1: fcp@fea2f000 { + compatible = "renesas,r8a7795-fcpv", "renesas,fcpv"; + reg = <0 0xfea2f000 0 0x200>; + clocks = <&cpg CPG_MOD 602>; + }; -- cgit v1.3-14-g43fede From 94fcdf829793b141dc93e20a2bbd9eeaa44ea25f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 11 Feb 2016 22:49:14 -0200 Subject: [media] v4l: vsp1: Add FCP support On some platforms the VSP performs memory accesses through an FCP. When that's the case get a reference to the FCP from the VSP DT node and enable/disable it at runtime as needed. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/renesas,vsp1.txt | 5 +++++ drivers/media/platform/Kconfig | 1 + drivers/media/platform/vsp1/vsp1.h | 2 ++ drivers/media/platform/vsp1/vsp1_drv.c | 21 ++++++++++++++++++++- 4 files changed, 28 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt index 627405abd144..9b695bcbf219 100644 --- a/Documentation/devicetree/bindings/media/renesas,vsp1.txt +++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt @@ -14,6 +14,11 @@ Required properties: - interrupts: VSP interrupt specifier. - clocks: A phandle + clock-specifier pair for the VSP functional clock. +Optional properties: + + - renesas,fcp: A phandle referencing the FCP that handles memory accesses + for the VSP. Not needed on Gen2, mandatory on Gen3. + Example: R8A7790 (R-Car H2) VSP1-S node diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index d6fe4fe924e7..9d0a3ffe36d2 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -265,6 +265,7 @@ config VIDEO_RENESAS_VSP1 tristate "Renesas VSP1 Video Processing Engine" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA depends on (ARCH_RENESAS && OF) || COMPILE_TEST + depends on !ARM64 || VIDEO_RENESAS_FCP select VIDEOBUF2_DMA_CONTIG ---help--- This is a V4L2 driver for the Renesas VSP1 video processing engine. diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h index 37cc05e34de0..7cb0f5e428df 100644 --- a/drivers/media/platform/vsp1/vsp1.h +++ b/drivers/media/platform/vsp1/vsp1.h @@ -25,6 +25,7 @@ struct clk; struct device; +struct rcar_fcp_device; struct vsp1_drm; struct vsp1_entity; @@ -62,6 +63,7 @@ struct vsp1_device { const struct vsp1_device_info *info; void __iomem *mmio; + struct rcar_fcp_device *fcp; struct vsp1_bru *bru; struct vsp1_hsit *hsi; diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 13907d4f08af..e655639af7e2 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -22,6 +22,7 @@ #include #include +#include #include #include "vsp1.h" @@ -514,6 +515,10 @@ static int vsp1_pm_resume(struct device *dev) static int vsp1_pm_runtime_suspend(struct device *dev) { + struct vsp1_device *vsp1 = dev_get_drvdata(dev); + + rcar_fcp_disable(vsp1->fcp); + return 0; } @@ -528,7 +533,7 @@ static int vsp1_pm_runtime_resume(struct device *dev) return ret; } - return 0; + return rcar_fcp_enable(vsp1->fcp); } static const struct dev_pm_ops vsp1_pm_ops = { @@ -614,6 +619,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = { static int vsp1_probe(struct platform_device *pdev) { struct vsp1_device *vsp1; + struct device_node *fcp_node; struct resource *irq; struct resource *io; unsigned int i; @@ -649,6 +655,18 @@ static int vsp1_probe(struct platform_device *pdev) return ret; } + /* FCP (optional) */ + fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0); + if (fcp_node) { + vsp1->fcp = rcar_fcp_get(fcp_node); + of_node_put(fcp_node); + if (IS_ERR(vsp1->fcp)) { + dev_dbg(&pdev->dev, "FCP not found (%ld)\n", + PTR_ERR(vsp1->fcp)); + return PTR_ERR(vsp1->fcp); + } + } + /* Configure device parameters based on the version register. */ pm_runtime_enable(&pdev->dev); @@ -694,6 +712,7 @@ static int vsp1_remove(struct platform_device *pdev) struct vsp1_device *vsp1 = platform_get_drvdata(pdev); vsp1_destroy_entities(vsp1); + rcar_fcp_put(vsp1->fcp); pm_runtime_disable(&pdev->dev); -- cgit v1.3-14-g43fede From e456cd37bc28abe47dc65189df916ac0510ac1d4 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 9 Jun 2016 16:53:48 +0200 Subject: i2c: smbus: add SMBus Host Notify support SMBus Host Notify allows a slave device to act as a master on a bus to notify the host of an interrupt. On Intel chipsets, the functionality is directly implemented in the firmware. We just need to export a function to call .alert() on the proper device driver. i2c_handle_smbus_host_notify() behaves like i2c_handle_smbus_alert(). When called, it schedules a task that will be able to sleep to go through the list of devices attached to the adapter. The current implementation allows one Host Notification to be scheduled while an other is running. Tested-by: Andrew Duggan Signed-off-by: Benjamin Tissoires Signed-off-by: Wolfram Sang --- Documentation/i2c/smbus-protocol | 6 +++ drivers/i2c/i2c-smbus.c | 113 +++++++++++++++++++++++++++++++++++++-- include/linux/i2c-smbus.h | 44 +++++++++++++++ include/linux/i2c.h | 3 ++ include/uapi/linux/i2c.h | 1 + 5 files changed, 162 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol index 6012b12b3510..14d4ec1be245 100644 --- a/Documentation/i2c/smbus-protocol +++ b/Documentation/i2c/smbus-protocol @@ -199,6 +199,12 @@ alerting device's address. [S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P] +This is implemented in the following way in the Linux kernel: +* I2C bus drivers which support SMBus Host Notify should call + i2c_setup_smbus_host_notify() to setup SMBus Host Notify support. +* I2C drivers for devices which can trigger SMBus Host Notify should implement + the optional alert() callback. + Packet Error Checking (PEC) =========================== diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 3b6765a4ebe9..f574995b41c1 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -33,7 +33,8 @@ struct i2c_smbus_alert { struct alert_data { unsigned short addr; - u8 flag:1; + enum i2c_alert_protocol type; + unsigned int data; }; /* If this is the alerting device, notify its driver */ @@ -56,8 +57,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) if (client->dev.driver) { driver = to_i2c_driver(client->dev.driver); if (driver->alert) - driver->alert(client, I2C_PROTOCOL_SMBUS_ALERT, - data->flag); + driver->alert(client, data->type, data->data); else dev_warn(&client->dev, "no driver alert()!\n"); } else @@ -97,8 +97,9 @@ static void smbus_alert(struct work_struct *work) if (status < 0) break; - data.flag = status & 1; + data.data = status & 1; data.addr = status >> 1; + data.type = I2C_PROTOCOL_SMBUS_ALERT; if (data.addr == prev_addr) { dev_warn(&ara->dev, "Duplicate SMBALERT# from dev " @@ -106,7 +107,7 @@ static void smbus_alert(struct work_struct *work) break; } dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n", - data.addr, data.flag); + data.addr, data.data); /* Notify driver for the device which issued the alert */ device_for_each_child(&ara->adapter->dev, &data, @@ -240,6 +241,108 @@ int i2c_handle_smbus_alert(struct i2c_client *ara) } EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert); +static void smbus_host_notify_work(struct work_struct *work) +{ + struct alert_data alert; + struct i2c_adapter *adapter; + unsigned long flags; + u16 payload; + u8 addr; + struct smbus_host_notify *data; + + data = container_of(work, struct smbus_host_notify, work); + + spin_lock_irqsave(&data->lock, flags); + payload = data->payload; + addr = data->addr; + adapter = data->adapter; + + /* clear the pending bit and release the spinlock */ + data->pending = false; + spin_unlock_irqrestore(&data->lock, flags); + + if (!adapter || !addr) + return; + + alert.type = I2C_PROTOCOL_SMBUS_HOST_NOTIFY; + alert.addr = addr; + alert.data = payload; + + device_for_each_child(&adapter->dev, &alert, smbus_do_alert); +} + +/** + * i2c_setup_smbus_host_notify - Allocate a new smbus_host_notify for the given + * I2C adapter. + * @adapter: the adapter we want to associate a Host Notify function + * + * Returns a struct smbus_host_notify pointer on success, and NULL on failure. + * The resulting smbus_host_notify must not be freed afterwards, it is a + * managed resource already. + */ +struct smbus_host_notify *i2c_setup_smbus_host_notify(struct i2c_adapter *adap) +{ + struct smbus_host_notify *host_notify; + + host_notify = devm_kzalloc(&adap->dev, sizeof(struct smbus_host_notify), + GFP_KERNEL); + if (!host_notify) + return NULL; + + host_notify->adapter = adap; + + spin_lock_init(&host_notify->lock); + INIT_WORK(&host_notify->work, smbus_host_notify_work); + + return host_notify; +} +EXPORT_SYMBOL_GPL(i2c_setup_smbus_host_notify); + +/** + * i2c_handle_smbus_host_notify - Forward a Host Notify event to the correct + * I2C client. + * @host_notify: the struct host_notify attached to the relevant adapter + * @data: the Host Notify data which contains the payload and address of the + * client + * Context: can't sleep + * + * Helper function to be called from an I2C bus driver's interrupt + * handler. It will schedule the Host Notify work, in turn calling the + * corresponding I2C device driver's alert function. + * + * host_notify should be a valid pointer previously returned by + * i2c_setup_smbus_host_notify(). + */ +int i2c_handle_smbus_host_notify(struct smbus_host_notify *host_notify, + unsigned short addr, unsigned int data) +{ + unsigned long flags; + struct i2c_adapter *adapter; + + if (!host_notify || !host_notify->adapter) + return -EINVAL; + + adapter = host_notify->adapter; + + spin_lock_irqsave(&host_notify->lock, flags); + + if (host_notify->pending) { + spin_unlock_irqrestore(&host_notify->lock, flags); + dev_warn(&adapter->dev, "Host Notify already scheduled.\n"); + return -EBUSY; + } + + host_notify->payload = data; + host_notify->addr = addr; + + /* Mark that there is a pending notification and release the lock */ + host_notify->pending = true; + spin_unlock_irqrestore(&host_notify->lock, flags); + + return schedule_work(&host_notify->work); +} +EXPORT_SYMBOL_GPL(i2c_handle_smbus_host_notify); + module_i2c_driver(smbalert_driver); MODULE_AUTHOR("Jean Delvare "); diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h index 8f1b086ca5bc..4ac95bbe53ef 100644 --- a/include/linux/i2c-smbus.h +++ b/include/linux/i2c-smbus.h @@ -23,6 +23,8 @@ #define _LINUX_I2C_SMBUS_H #include +#include +#include /** @@ -48,4 +50,46 @@ struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter, struct i2c_smbus_alert_setup *setup); int i2c_handle_smbus_alert(struct i2c_client *ara); +/** + * smbus_host_notify - internal structure used by the Host Notify mechanism. + * @adapter: the I2C adapter associated with this struct + * @work: worker used to schedule the IRQ in the slave device + * @lock: spinlock to check if a notification is already pending + * @pending: flag set when a notification is pending (any new notification will + * be rejected if pending is true) + * @payload: the actual payload of the Host Notify event + * @addr: the address of the slave device which raised the notification + * + * This struct needs to be allocated by i2c_setup_smbus_host_notify() and does + * not need to be freed. Internally, i2c_setup_smbus_host_notify() uses a + * managed resource to clean this up when the adapter get released. + */ +struct smbus_host_notify { + struct i2c_adapter *adapter; + struct work_struct work; + spinlock_t lock; + bool pending; + u16 payload; + u8 addr; +}; + +#if IS_ENABLED(CONFIG_I2C_SMBUS) +struct smbus_host_notify *i2c_setup_smbus_host_notify(struct i2c_adapter *adap); +int i2c_handle_smbus_host_notify(struct smbus_host_notify *host_notify, + unsigned short addr, unsigned int data); +#else +static inline struct smbus_host_notify * +i2c_setup_smbus_host_notify(struct i2c_adapter *adap) +{ + return NULL; +} + +static inline int +i2c_handle_smbus_host_notify(struct smbus_host_notify *host_notify, + unsigned short addr, unsigned int data) +{ + return 0; +} +#endif /* I2C_SMBUS */ + #endif /* _LINUX_I2C_SMBUS_H */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 37a45dcd6592..fffdc270ca18 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -128,6 +128,7 @@ i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, enum i2c_alert_protocol { I2C_PROTOCOL_SMBUS_ALERT, + I2C_PROTOCOL_SMBUS_HOST_NOTIFY, }; /** @@ -184,6 +185,8 @@ struct i2c_driver { * The format and meaning of the data value depends on the protocol. * For the SMBus alert protocol, there is a single bit of data passed * as the alert response's low bit ("event flag"). + * For the SMBus Host Notify protocol, the data corresponds to the + * 16-bit payload data reported by the slave device acting as master. */ void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol, unsigned int data); diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h index adcbef4bff61..009e27bb9abe 100644 --- a/include/uapi/linux/i2c.h +++ b/include/uapi/linux/i2c.h @@ -102,6 +102,7 @@ struct i2c_msg { #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ +#define I2C_FUNC_SMBUS_HOST_NOTIFY 0x10000000 #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ I2C_FUNC_SMBUS_WRITE_BYTE) -- cgit v1.3-14-g43fede From 908dbd539135f8bea04039dad1a667a3a36d7b42 Mon Sep 17 00:00:00 2001 From: David Wu Date: Mon, 16 May 2016 22:04:12 +0800 Subject: dt-bindings: i2c: rk3x: add support for rk3399 The bus clock and function clock are separated at rk3399, and others use one clock as the bus clock and function clock. Signed-off-by: David Wu Reviewed-by: Douglas Anderson Reviewed-by: Heiko Stuebner Tested-by: Heiko Stuebner Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-rk3x.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt index 0b4a85fe2d86..bbc5a1ed5fa1 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt @@ -6,10 +6,20 @@ RK3xxx SoCs. Required properties : - reg : Offset and length of the register set for the device - - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c", - "rockchip,rk3228-i2c" or "rockchip,rk3288-i2c". + - compatible: should be one of the following: + - "rockchip,rk3066-i2c": for rk3066 + - "rockchip,rk3188-i2c": for rk3188 + - "rockchip,rk3228-i2c": for rk3228 + - "rockchip,rk3288-i2c": for rk3288 + - "rockchip,rk3399-i2c": for rk3399 - interrupts : interrupt number - - clocks : parent clock + - clocks: See ../clock/clock-bindings.txt + - For older hardware (rk3066, rk3188, rk3228, rk3288): + - There is one clock that's used both to derive the functional clock + for the device and as the bus clock. + - For newer hardware (rk3399): specified by name + - "i2c": This is used to derive the functional clock. + - "pclk": This is the bus clock. Required on RK3066, RK3188 : -- cgit v1.3-14-g43fede From 9be05c7f372940a2308e0301c5bdddab3022a449 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 17 Jun 2016 15:35:28 +0200 Subject: can: bcm: add documentation for CAN FD support Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- Documentation/networking/can.txt | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index d58ff8467953..aa15b9ee2e70 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -31,6 +31,7 @@ This file contains 4.2.4 Broadcast Manager message sequence transmission 4.2.5 Broadcast Manager receive filter timers 4.2.6 Broadcast Manager multiplex message receive filter + 4.2.7 Broadcast Manager CAN FD support 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) @@ -799,7 +800,7 @@ solution for a couple of reasons: } mytxmsg; (..) - mytxmsg.nframes = 4; + mytxmsg.msg_head.nframes = 4; (..) write(s, &mytxmsg, sizeof(mytxmsg)); @@ -852,6 +853,28 @@ solution for a couple of reasons: write(s, &msg, sizeof(msg)); + 4.2.7 Broadcast Manager CAN FD support + + The programming API of the CAN_BCM depends on struct can_frame which is + given as array directly behind the bcm_msg_head structure. To follow this + schema for the CAN FD frames a new flag 'CAN_FD_FRAME' in the bcm_msg_head + flags indicates that the concatenated CAN frame structures behind the + bcm_msg_head are defined as struct canfd_frame. + + struct { + struct bcm_msg_head msg_head; + struct canfd_frame frame[5]; + } msg; + + msg.msg_head.opcode = RX_SETUP; + msg.msg_head.can_id = 0x42; + msg.msg_head.flags = CAN_FD_FRAME; + msg.msg_head.nframes = 5; + (..) + + When using CAN FD frames for multiplex filtering the MUX mask is still + expected in the first 64 bit of the struct canfd_frame data section. + 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) -- cgit v1.3-14-g43fede From dd3bd23eb438919aeeb73a7116642731ef8f73a8 Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Fri, 17 Jun 2016 09:20:55 +0100 Subject: can: rcar_canfd: Add Renesas R-Car CAN FD driver This patch adds support for the CAN FD controller found in Renesas R-Car SoCs. The controller operates in CAN FD only mode by default. CAN FD mode supports both Classical CAN & CAN FD frame formats. The controller supports ISO 11898-1:2015 CAN FD format only. This controller supports two channels and the driver can enable either or both of the channels. Driver uses Rx FIFOs (one per channel) for reception & Common FIFOs (one per channel) for transmission. Rx filter rules are configured to the minimum (one per channel) and it accepts Standard, Extended, Data & Remote Frame combinations. Note: There are few documentation errors in R-Car Gen3 Hardware User Manual v0.5E with respect to CAN FD controller. They are listed below: 1. CAN FD interrupt numbers 29 & 30 are listed as per channel interrupts. However, they are common to both channels (i.e.) they are global and channel interrupts respectively. 2. CANFD clock is derived from PLL1. This is not documented. 3. CANFD clock is further divided by (1/2) within the CAN FD controller. This is not documented. 4. The minimum value of NTSEG1 in RSCFDnCFDCmNCFG register is 2 Tq. It is specified 4 Tq in the manual. 5. The maximum number of message RAM area the controller can use is 3584 bytes. It is specified 10752 bytes in the manual. Signed-off-by: Ramesh Shanmugasundaram Acked-by: Rob Herring Reviewed-by: Ulrich Hecht Signed-off-by: Marc Kleine-Budde --- .../devicetree/bindings/net/can/rcar_canfd.txt | 89 + drivers/net/can/Kconfig | 1 + drivers/net/can/Makefile | 1 + drivers/net/can/rcar/Kconfig | 11 + drivers/net/can/rcar/Makefile | 5 + drivers/net/can/rcar/rcar_canfd.c | 1695 ++++++++++++++++++++ 6 files changed, 1802 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/rcar_canfd.txt create mode 100644 drivers/net/can/rcar/Kconfig create mode 100644 drivers/net/can/rcar/Makefile create mode 100644 drivers/net/can/rcar/rcar_canfd.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt new file mode 100644 index 000000000000..d45182bd21dd --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt @@ -0,0 +1,89 @@ +Renesas R-Car CAN FD controller Device Tree Bindings +---------------------------------------------------- + +Required properties: +- compatible: Must contain one or more of the following: + - "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller. + - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first, followed by the + family-specific and/or generic versions. + +- reg: physical base address and size of the R-Car CAN FD register map. +- interrupts: interrupt specifier for the Global & Channel interrupts +- clocks: phandles and clock specifiers for 3 clock inputs. +- clock-names: 3 clock input name strings: "fck", "canfd", "can_clk". +- pinctrl-0: pin control group to be used for this controller. +- pinctrl-names: must be "default". + +Required child nodes: +The controller supports two channels and each is represented as a child node. +The name of the child nodes are "channel0" and "channel1" respectively. Each +child node supports the "status" property only, which is used to +enable/disable the respective channel. + +Required properties for "renesas,r8a7795-canfd" compatible: +In R8A7795 SoC, canfd clock is a div6 clock and can be used by both CAN +and CAN FD controller at the same time. It needs to be scaled to maximum +frequency if any of these controllers use it. This is done using the +below properties. + +- assigned-clocks: phandle of canfd clock. +- assigned-clock-rates: maximum frequency of this clock. + +Example +------- + +SoC common .dtsi file: + + canfd: can@e66c0000 { + compatible = "renesas,r8a7795-canfd", + "renesas,rcar-gen3-canfd"; + reg = <0 0xe66c0000 0 0x8000>; + interrupts = , + ; + clocks = <&cpg CPG_MOD 914>, + <&cpg CPG_CORE R8A7795_CLK_CANFD>, + <&can_clk>; + clock-names = "fck", "canfd", "can_clk"; + assigned-clocks = <&cpg CPG_CORE R8A7795_CLK_CANFD>; + assigned-clock-rates = <40000000>; + power-domains = <&cpg>; + status = "disabled"; + + channel0 { + status = "disabled"; + }; + + channel1 { + status = "disabled"; + }; + }; + +Board specific .dts file: + +E.g. below enables Channel 1 alone in the board. + +&canfd { + pinctrl-0 = <&canfd1_pins>; + pinctrl-names = "default"; + status = "okay"; + + channel1 { + status = "okay"; + }; +}; + +E.g. below enables Channel 0 alone in the board using External clock +as fCAN clock. + +&canfd { + pinctrl-0 = <&canfd0_pins &can_clk_pins>; + pinctrl-names = "default"; + status = "okay"; + + channel0 { + status = "okay"; + }; +}; diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 0d40aef928e2..13003a9472f2 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -152,6 +152,7 @@ source "drivers/net/can/cc770/Kconfig" source "drivers/net/can/ifi_canfd/Kconfig" source "drivers/net/can/m_can/Kconfig" source "drivers/net/can/mscan/Kconfig" +source "drivers/net/can/rcar/Kconfig" source "drivers/net/can/sja1000/Kconfig" source "drivers/net/can/softing/Kconfig" source "drivers/net/can/spi/Kconfig" diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index e3db0c807f55..226d5b516746 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -10,6 +10,7 @@ can-dev-y := dev.o can-dev-$(CONFIG_CAN_LEDS) += led.o +obj-y += rcar/ obj-y += spi/ obj-y += usb/ obj-y += softing/ diff --git a/drivers/net/can/rcar/Kconfig b/drivers/net/can/rcar/Kconfig new file mode 100644 index 000000000000..6ea64d19ec26 --- /dev/null +++ b/drivers/net/can/rcar/Kconfig @@ -0,0 +1,11 @@ +config CAN_RCAR_CANFD + tristate "Renesas R-Car CAN FD controller" + depends on ARCH_RENESAS || ARM + ---help--- + Say Y here if you want to use CAN FD controller found on + Renesas R-Car SoCs. The driver puts the controller in CAN FD only + mode, which can interoperate with CAN2.0 nodes but does not support + dedicated CAN 2.0 mode. + + To compile this driver as a module, choose M here: the module will + be called rcar_canfd. diff --git a/drivers/net/can/rcar/Makefile b/drivers/net/can/rcar/Makefile new file mode 100644 index 000000000000..cbaf498e1ac7 --- /dev/null +++ b/drivers/net/can/rcar/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Renesas R-Car CAN FD controller driver +# + +obj-$(CONFIG_CAN_RCAR_CANFD) += rcar_canfd.o diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c new file mode 100644 index 000000000000..a39d9224166c --- /dev/null +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -0,0 +1,1695 @@ +/* Renesas R-Car CAN FD device driver + * + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* The R-Car CAN FD controller can operate in either one of the below two modes + * - CAN FD only mode + * - Classical CAN (CAN 2.0) only mode + * + * This driver puts the controller in CAN FD only mode by default. In this + * mode, the controller acts as a CAN FD node that can also interoperate with + * CAN 2.0 nodes. + * + * As of now, this driver does not support the Classical CAN (CAN 2.0) mode, + * which is handled by a different register map compared to CAN FD only mode. + * + * Note: The h/w manual register naming convention is clumsy and not acceptable + * to use as it is in the driver. However, those names are added as comments + * wherever it is modified to a readable name. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RCANFD_DRV_NAME "rcar_canfd" + +/* Global register bits */ + +/* RSCFDnCFDGRMCFG */ +#define RCANFD_GRMCFG_RCMC BIT(0) + +/* RSCFDnCFDGCFG */ +#define RCANFD_GCFG_CMPOC BIT(5) +#define RCANFD_GCFG_DCS BIT(4) +#define RCANFD_GCFG_DCE BIT(1) +#define RCANFD_GCFG_TPRI BIT(0) + +/* RSCFDnCFDGCTR */ +#define RCANFD_GCTR_TSRST BIT(16) +#define RCANFD_GCTR_CFMPOFIE BIT(11) +#define RCANFD_GCTR_THLEIE BIT(10) +#define RCANFD_GCTR_MEIE BIT(9) +#define RCANFD_GCTR_DEIE BIT(8) +#define RCANFD_GCTR_GSLPR BIT(2) +#define RCANFD_GCTR_GMDC_MASK (0x3) +#define RCANFD_GCTR_GMDC_GOPM (0x0) +#define RCANFD_GCTR_GMDC_GRESET (0x1) +#define RCANFD_GCTR_GMDC_GTEST (0x2) + +/* RSCFDnCFDGSTS */ +#define RCANFD_GSTS_GRAMINIT BIT(3) +#define RCANFD_GSTS_GSLPSTS BIT(2) +#define RCANFD_GSTS_GHLTSTS BIT(1) +#define RCANFD_GSTS_GRSTSTS BIT(0) +/* Non-operational status */ +#define RCANFD_GSTS_GNOPM (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +/* RSCFDnCFDGERFL */ +#define RCANFD_GERFL_EEF1 BIT(17) +#define RCANFD_GERFL_EEF0 BIT(16) +#define RCANFD_GERFL_CMPOF BIT(3) +#define RCANFD_GERFL_THLES BIT(2) +#define RCANFD_GERFL_MES BIT(1) +#define RCANFD_GERFL_DEF BIT(0) + +#define RCANFD_GERFL_ERR(x) ((x) & (RCANFD_GERFL_EEF1 |\ + RCANFD_GERFL_EEF0 |\ + RCANFD_GERFL_MES |\ + RCANFD_GERFL_CMPOF)) + +/* AFL Rx rules registers */ + +/* RSCFDnCFDGAFLCFG0 */ +#define RCANFD_GAFLCFG_SETRNC(n, x) (((x) & 0xff) << (24 - n * 8)) +#define RCANFD_GAFLCFG_GETRNC(n, x) (((x) >> (24 - n * 8)) & 0xff) + +/* RSCFDnCFDGAFLECTR */ +#define RCANFD_GAFLECTR_AFLDAE BIT(8) +#define RCANFD_GAFLECTR_AFLPN(x) ((x) & 0x1f) + +/* RSCFDnCFDGAFLIDj */ +#define RCANFD_GAFLID_GAFLLB BIT(29) + +/* RSCFDnCFDGAFLP1_j */ +#define RCANFD_GAFLP1_GAFLFDP(x) (1 << (x)) + +/* Channel register bits */ + +/* RSCFDnCFDCmNCFG */ +#define RCANFD_NCFG_NTSEG2(x) (((x) & 0x1f) << 24) +#define RCANFD_NCFG_NTSEG1(x) (((x) & 0x7f) << 16) +#define RCANFD_NCFG_NSJW(x) (((x) & 0x1f) << 11) +#define RCANFD_NCFG_NBRP(x) (((x) & 0x3ff) << 0) + +/* RSCFDnCFDCmCTR */ +#define RCANFD_CCTR_CTME BIT(24) +#define RCANFD_CCTR_ERRD BIT(23) +#define RCANFD_CCTR_BOM_MASK (0x3 << 21) +#define RCANFD_CCTR_BOM_ISO (0x0 << 21) +#define RCANFD_CCTR_BOM_BENTRY (0x1 << 21) +#define RCANFD_CCTR_BOM_BEND (0x2 << 21) +#define RCANFD_CCTR_TDCVFIE BIT(19) +#define RCANFD_CCTR_SOCOIE BIT(18) +#define RCANFD_CCTR_EOCOIE BIT(17) +#define RCANFD_CCTR_TAIE BIT(16) +#define RCANFD_CCTR_ALIE BIT(15) +#define RCANFD_CCTR_BLIE BIT(14) +#define RCANFD_CCTR_OLIE BIT(13) +#define RCANFD_CCTR_BORIE BIT(12) +#define RCANFD_CCTR_BOEIE BIT(11) +#define RCANFD_CCTR_EPIE BIT(10) +#define RCANFD_CCTR_EWIE BIT(9) +#define RCANFD_CCTR_BEIE BIT(8) +#define RCANFD_CCTR_CSLPR BIT(2) +#define RCANFD_CCTR_CHMDC_MASK (0x3) +#define RCANFD_CCTR_CHDMC_COPM (0x0) +#define RCANFD_CCTR_CHDMC_CRESET (0x1) +#define RCANFD_CCTR_CHDMC_CHLT (0x2) + +/* RSCFDnCFDCmSTS */ +#define RCANFD_CSTS_COMSTS BIT(7) +#define RCANFD_CSTS_RECSTS BIT(6) +#define RCANFD_CSTS_TRMSTS BIT(5) +#define RCANFD_CSTS_BOSTS BIT(4) +#define RCANFD_CSTS_EPSTS BIT(3) +#define RCANFD_CSTS_SLPSTS BIT(2) +#define RCANFD_CSTS_HLTSTS BIT(1) +#define RCANFD_CSTS_CRSTSTS BIT(0) + +#define RCANFD_CSTS_TECCNT(x) (((x) >> 24) & 0xff) +#define RCANFD_CSTS_RECCNT(x) (((x) >> 16) & 0xff) + +/* RSCFDnCFDCmERFL */ +#define RCANFD_CERFL_ADERR BIT(14) +#define RCANFD_CERFL_B0ERR BIT(13) +#define RCANFD_CERFL_B1ERR BIT(12) +#define RCANFD_CERFL_CERR BIT(11) +#define RCANFD_CERFL_AERR BIT(10) +#define RCANFD_CERFL_FERR BIT(9) +#define RCANFD_CERFL_SERR BIT(8) +#define RCANFD_CERFL_ALF BIT(7) +#define RCANFD_CERFL_BLF BIT(6) +#define RCANFD_CERFL_OVLF BIT(5) +#define RCANFD_CERFL_BORF BIT(4) +#define RCANFD_CERFL_BOEF BIT(3) +#define RCANFD_CERFL_EPF BIT(2) +#define RCANFD_CERFL_EWF BIT(1) +#define RCANFD_CERFL_BEF BIT(0) + +#define RCANFD_CERFL_ERR(x) ((x) & (0x7fff)) /* above bits 14:0 */ + +/* RSCFDnCFDCmDCFG */ +#define RCANFD_DCFG_DSJW(x) (((x) & 0x7) << 24) +#define RCANFD_DCFG_DTSEG2(x) (((x) & 0x7) << 20) +#define RCANFD_DCFG_DTSEG1(x) (((x) & 0xf) << 16) +#define RCANFD_DCFG_DBRP(x) (((x) & 0xff) << 0) + +/* RSCFDnCFDCmFDCFG */ +#define RCANFD_FDCFG_TDCE BIT(9) +#define RCANFD_FDCFG_TDCOC BIT(8) +#define RCANFD_FDCFG_TDCO(x) (((x) & 0x7f) >> 16) + +/* RSCFDnCFDRFCCx */ +#define RCANFD_RFCC_RFIM BIT(12) +#define RCANFD_RFCC_RFDC(x) (((x) & 0x7) << 8) +#define RCANFD_RFCC_RFPLS(x) (((x) & 0x7) << 4) +#define RCANFD_RFCC_RFIE BIT(1) +#define RCANFD_RFCC_RFE BIT(0) + +/* RSCFDnCFDRFSTSx */ +#define RCANFD_RFSTS_RFIF BIT(3) +#define RCANFD_RFSTS_RFMLT BIT(2) +#define RCANFD_RFSTS_RFFLL BIT(1) +#define RCANFD_RFSTS_RFEMP BIT(0) + +/* RSCFDnCFDRFIDx */ +#define RCANFD_RFID_RFIDE BIT(31) +#define RCANFD_RFID_RFRTR BIT(30) + +/* RSCFDnCFDRFPTRx */ +#define RCANFD_RFPTR_RFDLC(x) (((x) >> 28) & 0xf) +#define RCANFD_RFPTR_RFPTR(x) (((x) >> 16) & 0xfff) +#define RCANFD_RFPTR_RFTS(x) (((x) >> 0) & 0xffff) + +/* RSCFDnCFDRFFDSTSx */ +#define RCANFD_RFFDSTS_RFFDF BIT(2) +#define RCANFD_RFFDSTS_RFBRS BIT(1) +#define RCANFD_RFFDSTS_RFESI BIT(0) + +/* Common FIFO bits */ + +/* RSCFDnCFDCFCCk */ +#define RCANFD_CFCC_CFTML(x) (((x) & 0xf) << 20) +#define RCANFD_CFCC_CFM(x) (((x) & 0x3) << 16) +#define RCANFD_CFCC_CFIM BIT(12) +#define RCANFD_CFCC_CFDC(x) (((x) & 0x7) << 8) +#define RCANFD_CFCC_CFPLS(x) (((x) & 0x7) << 4) +#define RCANFD_CFCC_CFTXIE BIT(2) +#define RCANFD_CFCC_CFE BIT(0) + +/* RSCFDnCFDCFSTSk */ +#define RCANFD_CFSTS_CFMC(x) (((x) >> 8) & 0xff) +#define RCANFD_CFSTS_CFTXIF BIT(4) +#define RCANFD_CFSTS_CFMLT BIT(2) +#define RCANFD_CFSTS_CFFLL BIT(1) +#define RCANFD_CFSTS_CFEMP BIT(0) + +/* RSCFDnCFDCFIDk */ +#define RCANFD_CFID_CFIDE BIT(31) +#define RCANFD_CFID_CFRTR BIT(30) +#define RCANFD_CFID_CFID_MASK(x) ((x) & 0x1fffffff) + +/* RSCFDnCFDCFPTRk */ +#define RCANFD_CFPTR_CFDLC(x) (((x) & 0xf) << 28) +#define RCANFD_CFPTR_CFPTR(x) (((x) & 0xfff) << 16) +#define RCANFD_CFPTR_CFTS(x) (((x) & 0xff) << 0) + +/* RSCFDnCFDCFFDCSTSk */ +#define RCANFD_CFFDCSTS_CFFDF BIT(2) +#define RCANFD_CFFDCSTS_CFBRS BIT(1) +#define RCANFD_CFFDCSTS_CFESI BIT(0) + +/* This controller supports classical CAN only mode or CAN FD only mode. These + * modes are supported in two separate set of register maps & names. However, + * some of the register offsets are common for both modes. Those offsets are + * listed below as Common registers. + * + * The CAN FD only specific registers are listed separately and their names + * starts with RCANFD_F_xxx names. When classical CAN only specific registers + * are added, those specific registers can be prefixed as RCANFD_C_xxx. + */ + +/* Common registers */ + +/* RSCFDnCFDCmNCFG / RSCFDnCmCFG */ +#define RCANFD_CCFG(m) (0x0000 + (0x10 * (m))) +/* RSCFDnCFDCmCTR / RSCFDnCmCTR */ +#define RCANFD_CCTR(m) (0x0004 + (0x10 * (m))) +/* RSCFDnCFDCmSTS / RSCFDnCmSTS */ +#define RCANFD_CSTS(m) (0x0008 + (0x10 * (m))) +/* RSCFDnCFDCmERFL / RSCFDnCmERFL */ +#define RCANFD_CERFL(m) (0x000C + (0x10 * (m))) + +/* RSCFDnCFDGCFG / RSCFDnGCFG */ +#define RCANFD_GCFG (0x0084) +/* RSCFDnCFDGCTR / RSCFDnGCTR */ +#define RCANFD_GCTR (0x0088) +/* RSCFDnCFDGCTS / RSCFDnGCTS */ +#define RCANFD_GSTS (0x008c) +/* RSCFDnCFDGERFL / RSCFDnGERFL */ +#define RCANFD_GERFL (0x0090) +/* RSCFDnCFDGTSC / RSCFDnGTSC */ +#define RCANFD_GTSC (0x0094) +/* RSCFDnCFDGAFLECTR / RSCFDnGAFLECTR */ +#define RCANFD_GAFLECTR (0x0098) +/* RSCFDnCFDGAFLCFG0 / RSCFDnGAFLCFG0 */ +#define RCANFD_GAFLCFG0 (0x009c) +/* RSCFDnCFDGAFLCFG1 / RSCFDnGAFLCFG1 */ +#define RCANFD_GAFLCFG1 (0x00a0) +/* RSCFDnCFDRMNB / RSCFDnRMNB */ +#define RCANFD_RMNB (0x00a4) +/* RSCFDnCFDRMND / RSCFDnRMND */ +#define RCANFD_RMND(y) (0x00a8 + (0x04 * (y))) + +/* RSCFDnCFDRFCCx / RSCFDnRFCCx */ +#define RCANFD_RFCC(x) (0x00b8 + (0x04 * (x))) +/* RSCFDnCFDRFSTSx / RSCFDnRFSTSx */ +#define RCANFD_RFSTS(x) (0x00d8 + (0x04 * (x))) +/* RSCFDnCFDRFPCTRx / RSCFDnRFPCTRx */ +#define RCANFD_RFPCTR(x) (0x00f8 + (0x04 * (x))) + +/* Common FIFO Control registers */ + +/* RSCFDnCFDCFCCx / RSCFDnCFCCx */ +#define RCANFD_CFCC(ch, idx) (0x0118 + (0x0c * (ch)) + \ + (0x04 * (idx))) +/* RSCFDnCFDCFSTSx / RSCFDnCFSTSx */ +#define RCANFD_CFSTS(ch, idx) (0x0178 + (0x0c * (ch)) + \ + (0x04 * (idx))) +/* RSCFDnCFDCFPCTRx / RSCFDnCFPCTRx */ +#define RCANFD_CFPCTR(ch, idx) (0x01d8 + (0x0c * (ch)) + \ + (0x04 * (idx))) + +/* RSCFDnCFDFESTS / RSCFDnFESTS */ +#define RCANFD_FESTS (0x0238) +/* RSCFDnCFDFFSTS / RSCFDnFFSTS */ +#define RCANFD_FFSTS (0x023c) +/* RSCFDnCFDFMSTS / RSCFDnFMSTS */ +#define RCANFD_FMSTS (0x0240) +/* RSCFDnCFDRFISTS / RSCFDnRFISTS */ +#define RCANFD_RFISTS (0x0244) +/* RSCFDnCFDCFRISTS / RSCFDnCFRISTS */ +#define RCANFD_CFRISTS (0x0248) +/* RSCFDnCFDCFTISTS / RSCFDnCFTISTS */ +#define RCANFD_CFTISTS (0x024c) + +/* RSCFDnCFDTMCp / RSCFDnTMCp */ +#define RCANFD_TMC(p) (0x0250 + (0x01 * (p))) +/* RSCFDnCFDTMSTSp / RSCFDnTMSTSp */ +#define RCANFD_TMSTS(p) (0x02d0 + (0x01 * (p))) + +/* RSCFDnCFDTMTRSTSp / RSCFDnTMTRSTSp */ +#define RCANFD_TMTRSTS(y) (0x0350 + (0x04 * (y))) +/* RSCFDnCFDTMTARSTSp / RSCFDnTMTARSTSp */ +#define RCANFD_TMTARSTS(y) (0x0360 + (0x04 * (y))) +/* RSCFDnCFDTMTCSTSp / RSCFDnTMTCSTSp */ +#define RCANFD_TMTCSTS(y) (0x0370 + (0x04 * (y))) +/* RSCFDnCFDTMTASTSp / RSCFDnTMTASTSp */ +#define RCANFD_TMTASTS(y) (0x0380 + (0x04 * (y))) +/* RSCFDnCFDTMIECy / RSCFDnTMIECy */ +#define RCANFD_TMIEC(y) (0x0390 + (0x04 * (y))) + +/* RSCFDnCFDTXQCCm / RSCFDnTXQCCm */ +#define RCANFD_TXQCC(m) (0x03a0 + (0x04 * (m))) +/* RSCFDnCFDTXQSTSm / RSCFDnTXQSTSm */ +#define RCANFD_TXQSTS(m) (0x03c0 + (0x04 * (m))) +/* RSCFDnCFDTXQPCTRm / RSCFDnTXQPCTRm */ +#define RCANFD_TXQPCTR(m) (0x03e0 + (0x04 * (m))) + +/* RSCFDnCFDTHLCCm / RSCFDnTHLCCm */ +#define RCANFD_THLCC(m) (0x0400 + (0x04 * (m))) +/* RSCFDnCFDTHLSTSm / RSCFDnTHLSTSm */ +#define RCANFD_THLSTS(m) (0x0420 + (0x04 * (m))) +/* RSCFDnCFDTHLPCTRm / RSCFDnTHLPCTRm */ +#define RCANFD_THLPCTR(m) (0x0440 + (0x04 * (m))) + +/* RSCFDnCFDGTINTSTS0 / RSCFDnGTINTSTS0 */ +#define RCANFD_GTINTSTS0 (0x0460) +/* RSCFDnCFDGTINTSTS1 / RSCFDnGTINTSTS1 */ +#define RCANFD_GTINTSTS1 (0x0464) +/* RSCFDnCFDGTSTCFG / RSCFDnGTSTCFG */ +#define RCANFD_GTSTCFG (0x0468) +/* RSCFDnCFDGTSTCTR / RSCFDnGTSTCTR */ +#define RCANFD_GTSTCTR (0x046c) +/* RSCFDnCFDGLOCKK / RSCFDnGLOCKK */ +#define RCANFD_GLOCKK (0x047c) +/* RSCFDnCFDGRMCFG / RSCFDnGRMCFG */ +#define RCANFD_GRMCFG (0x04fc) + +/* RSCFDnCFDGAFLIDj / RSCFDnGAFLIDj */ +#define RCANFD_GAFLID(offset, j) ((offset) + (0x10 * (j))) +/* RSCFDnCFDGAFLMj / RSCFDnGAFLMj */ +#define RCANFD_GAFLM(offset, j) ((offset) + 0x04 + (0x10 * (j))) +/* RSCFDnCFDGAFLP0j / RSCFDnGAFLP0j */ +#define RCANFD_GAFLP0(offset, j) ((offset) + 0x08 + (0x10 * (j))) +/* RSCFDnCFDGAFLP1j / RSCFDnGAFLP1j */ +#define RCANFD_GAFLP1(offset, j) ((offset) + 0x0c + (0x10 * (j))) + +/* CAN FD mode specific regsiter map */ + +/* RSCFDnCFDCmXXX -> RCANFD_F_XXX(m) */ +#define RCANFD_F_DCFG(m) (0x0500 + (0x20 * (m))) +#define RCANFD_F_CFDCFG(m) (0x0504 + (0x20 * (m))) +#define RCANFD_F_CFDCTR(m) (0x0508 + (0x20 * (m))) +#define RCANFD_F_CFDSTS(m) (0x050c + (0x20 * (m))) +#define RCANFD_F_CFDCRC(m) (0x0510 + (0x20 * (m))) + +/* RSCFDnCFDGAFLXXXj offset */ +#define RCANFD_F_GAFL_OFFSET (0x1000) + +/* RSCFDnCFDRMXXXq -> RCANFD_F_RMXXX(q) */ +#define RCANFD_F_RMID(q) (0x2000 + (0x20 * (q))) +#define RCANFD_F_RMPTR(q) (0x2004 + (0x20 * (q))) +#define RCANFD_F_RMFDSTS(q) (0x2008 + (0x20 * (q))) +#define RCANFD_F_RMDF(q, b) (0x200c + (0x04 * (b)) + (0x20 * (q))) + +/* RSCFDnCFDRFXXx -> RCANFD_F_RFXX(x) */ +#define RCANFD_F_RFOFFSET (0x3000) +#define RCANFD_F_RFID(x) (RCANFD_F_RFOFFSET + (0x80 * (x))) +#define RCANFD_F_RFPTR(x) (RCANFD_F_RFOFFSET + 0x04 + \ + (0x80 * (x))) +#define RCANFD_F_RFFDSTS(x) (RCANFD_F_RFOFFSET + 0x08 + \ + (0x80 * (x))) +#define RCANFD_F_RFDF(x, df) (RCANFD_F_RFOFFSET + 0x0c + \ + (0x80 * (x)) + (0x04 * (df))) + +/* RSCFDnCFDCFXXk -> RCANFD_F_CFXX(ch, k) */ +#define RCANFD_F_CFOFFSET (0x3400) +#define RCANFD_F_CFID(ch, idx) (RCANFD_F_CFOFFSET + (0x180 * (ch)) + \ + (0x80 * (idx))) +#define RCANFD_F_CFPTR(ch, idx) (RCANFD_F_CFOFFSET + 0x04 + \ + (0x180 * (ch)) + (0x80 * (idx))) +#define RCANFD_F_CFFDCSTS(ch, idx) (RCANFD_F_CFOFFSET + 0x08 + \ + (0x180 * (ch)) + (0x80 * (idx))) +#define RCANFD_F_CFDF(ch, idx, df) (RCANFD_F_CFOFFSET + 0x0c + \ + (0x180 * (ch)) + (0x80 * (idx)) + \ + (0x04 * (df))) + +/* RSCFDnCFDTMXXp -> RCANFD_F_TMXX(p) */ +#define RCANFD_F_TMID(p) (0x4000 + (0x20 * (p))) +#define RCANFD_F_TMPTR(p) (0x4004 + (0x20 * (p))) +#define RCANFD_F_TMFDCTR(p) (0x4008 + (0x20 * (p))) +#define RCANFD_F_TMDF(p, b) (0x400c + (0x20 * (p)) + (0x04 * (b))) + +/* RSCFDnCFDTHLACCm */ +#define RCANFD_F_THLACC(m) (0x6000 + (0x04 * (m))) +/* RSCFDnCFDRPGACCr */ +#define RCANFD_F_RPGACC(r) (0x6400 + (0x04 * (r))) + +/* Constants */ +#define RCANFD_FIFO_DEPTH 8 /* Tx FIFO depth */ +#define RCANFD_NAPI_WEIGHT 8 /* Rx poll quota */ + +#define RCANFD_NUM_CHANNELS 2 /* Two channels max */ +#define RCANFD_CHANNELS_MASK BIT((RCANFD_NUM_CHANNELS) - 1) + +#define RCANFD_GAFL_PAGENUM(entry) ((entry) / 16) +#define RCANFD_CHANNEL_NUMRULES 1 /* only one rule per channel */ + +/* Rx FIFO is a global resource of the controller. There are 8 such FIFOs + * available. Each channel gets a dedicated Rx FIFO (i.e.) the channel + * number is added to RFFIFO index. + */ +#define RCANFD_RFFIFO_IDX 0 + +/* Tx/Rx or Common FIFO is a per channel resource. Each channel has 3 Common + * FIFOs dedicated to them. Use the first (index 0) FIFO out of the 3 for Tx. + */ +#define RCANFD_CFFIFO_IDX 0 + +/* fCAN clock select register settings */ +enum rcar_canfd_fcanclk { + RCANFD_CANFDCLK = 0, /* CANFD clock */ + RCANFD_EXTCLK, /* Externally input clock */ +}; + +struct rcar_canfd_global; + +/* Channel priv data */ +struct rcar_canfd_channel { + struct can_priv can; /* Must be the first member */ + struct net_device *ndev; + struct rcar_canfd_global *gpriv; /* Controller reference */ + void __iomem *base; /* Register base address */ + struct napi_struct napi; + u8 tx_len[RCANFD_FIFO_DEPTH]; /* For net stats */ + u32 tx_head; /* Incremented on xmit */ + u32 tx_tail; /* Incremented on xmit done */ + u32 channel; /* Channel number */ + spinlock_t tx_lock; /* To protect tx path */ +}; + +/* Global priv data */ +struct rcar_canfd_global { + struct rcar_canfd_channel *ch[RCANFD_NUM_CHANNELS]; + void __iomem *base; /* Register base address */ + struct platform_device *pdev; /* Respective platform device */ + struct clk *clkp; /* Peripheral clock */ + struct clk *can_clk; /* fCAN clock */ + enum rcar_canfd_fcanclk fcan; /* CANFD or Ext clock */ + unsigned long channels_mask; /* Enabled channels mask */ +}; + +/* CAN FD mode nominal rate constants */ +static const struct can_bittiming_const rcar_canfd_nom_bittiming_const = { + .name = RCANFD_DRV_NAME, + .tseg1_min = 2, + .tseg1_max = 128, + .tseg2_min = 2, + .tseg2_max = 32, + .sjw_max = 32, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + +/* CAN FD mode data rate constants */ +static const struct can_bittiming_const rcar_canfd_data_bittiming_const = { + .name = RCANFD_DRV_NAME, + .tseg1_min = 2, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 8, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, +}; + +/* Helper functions */ +static inline void rcar_canfd_update(u32 mask, u32 val, u32 __iomem *reg) +{ + u32 data = readl(reg); + + data &= ~mask; + data |= (val & mask); + writel(data, reg); +} + +static inline u32 rcar_canfd_read(void __iomem *base, u32 offset) +{ + return readl(base + (offset)); +} + +static inline void rcar_canfd_write(void __iomem *base, u32 offset, u32 val) +{ + writel(val, base + (offset)); +} + +static void rcar_canfd_set_bit(void __iomem *base, u32 reg, u32 val) +{ + rcar_canfd_update(val, val, base + (reg)); +} + +static void rcar_canfd_clear_bit(void __iomem *base, u32 reg, u32 val) +{ + rcar_canfd_update(val, 0, base + (reg)); +} + +static void rcar_canfd_update_bit(void __iomem *base, u32 reg, + u32 mask, u32 val) +{ + rcar_canfd_update(mask, val, base + (reg)); +} + +static void rcar_canfd_get_data(struct rcar_canfd_channel *priv, + struct canfd_frame *cf, u32 off) +{ + u32 i, lwords; + + lwords = DIV_ROUND_UP(cf->len, sizeof(u32)); + for (i = 0; i < lwords; i++) + *((u32 *)cf->data + i) = + rcar_canfd_read(priv->base, off + (i * sizeof(u32))); +} + +static void rcar_canfd_put_data(struct rcar_canfd_channel *priv, + struct canfd_frame *cf, u32 off) +{ + u32 i, lwords; + + lwords = DIV_ROUND_UP(cf->len, sizeof(u32)); + for (i = 0; i < lwords; i++) + rcar_canfd_write(priv->base, off + (i * sizeof(u32)), + *((u32 *)cf->data + i)); +} + +static void rcar_canfd_tx_failure_cleanup(struct net_device *ndev) +{ + u32 i; + + for (i = 0; i < RCANFD_FIFO_DEPTH; i++) + can_free_echo_skb(ndev, i); +} + +static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) +{ + u32 sts, ch; + int err; + + /* Check RAMINIT flag as CAN RAM initialization takes place + * after the MCU reset + */ + err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts, + !(sts & RCANFD_GSTS_GRAMINIT), 2, 500000); + if (err) { + dev_dbg(&gpriv->pdev->dev, "global raminit failed\n"); + return err; + } + + /* Transition to Global Reset mode */ + rcar_canfd_clear_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR); + rcar_canfd_update_bit(gpriv->base, RCANFD_GCTR, + RCANFD_GCTR_GMDC_MASK, RCANFD_GCTR_GMDC_GRESET); + + /* Ensure Global reset mode */ + err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts, + (sts & RCANFD_GSTS_GRSTSTS), 2, 500000); + if (err) { + dev_dbg(&gpriv->pdev->dev, "global reset failed\n"); + return err; + } + + /* Reset Global error flags */ + rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0); + + /* Set the controller into FD mode */ + rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, RCANFD_GRMCFG_RCMC); + + /* Transition all Channels to reset mode */ + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + rcar_canfd_clear_bit(gpriv->base, + RCANFD_CCTR(ch), RCANFD_CCTR_CSLPR); + + rcar_canfd_update_bit(gpriv->base, RCANFD_CCTR(ch), + RCANFD_CCTR_CHMDC_MASK, + RCANFD_CCTR_CHDMC_CRESET); + + /* Ensure Channel reset mode */ + err = readl_poll_timeout((gpriv->base + RCANFD_CSTS(ch)), sts, + (sts & RCANFD_CSTS_CRSTSTS), + 2, 500000); + if (err) { + dev_dbg(&gpriv->pdev->dev, + "channel %u reset failed\n", ch); + return err; + } + } + return 0; +} + +static void rcar_canfd_configure_controller(struct rcar_canfd_global *gpriv) +{ + u32 cfg, ch; + + /* Global configuration settings */ + + /* Truncate payload to configured message size RFPLS */ + cfg = RCANFD_GCFG_CMPOC; + + /* Set External Clock if selected */ + if (gpriv->fcan != RCANFD_CANFDCLK) + cfg |= RCANFD_GCFG_DCS; + + rcar_canfd_set_bit(gpriv->base, RCANFD_GCFG, cfg); + + /* Channel configuration settings */ + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + rcar_canfd_set_bit(gpriv->base, RCANFD_CCTR(ch), + RCANFD_CCTR_ERRD); + rcar_canfd_update_bit(gpriv->base, RCANFD_CCTR(ch), + RCANFD_CCTR_BOM_MASK, + RCANFD_CCTR_BOM_BENTRY); + } +} + +static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv, + u32 ch) +{ + u32 cfg; + int start, page, num_rules = RCANFD_CHANNEL_NUMRULES; + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + if (ch == 0) { + start = 0; /* Channel 0 always starts from 0th rule */ + } else { + /* Get number of Channel 0 rules and adjust */ + cfg = rcar_canfd_read(gpriv->base, RCANFD_GAFLCFG0); + start = RCANFD_GAFLCFG_GETRNC(0, cfg); + } + + /* Enable write access to entry */ + page = RCANFD_GAFL_PAGENUM(start); + rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLECTR, + (RCANFD_GAFLECTR_AFLPN(page) | + RCANFD_GAFLECTR_AFLDAE)); + + /* Write number of rules for channel */ + rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLCFG0, + RCANFD_GAFLCFG_SETRNC(ch, num_rules)); + + /* Accept all IDs */ + rcar_canfd_write(gpriv->base, + RCANFD_GAFLID(RCANFD_F_GAFL_OFFSET, start), 0); + /* IDE or RTR is not considered for matching */ + rcar_canfd_write(gpriv->base, + RCANFD_GAFLM(RCANFD_F_GAFL_OFFSET, start), 0); + /* Any data length accepted */ + rcar_canfd_write(gpriv->base, + RCANFD_GAFLP0(RCANFD_F_GAFL_OFFSET, start), 0); + /* Place the msg in corresponding Rx FIFO entry */ + rcar_canfd_write(gpriv->base, + RCANFD_GAFLP1(RCANFD_F_GAFL_OFFSET, start), + RCANFD_GAFLP1_GAFLFDP(ridx)); + + /* Disable write access to page */ + rcar_canfd_clear_bit(gpriv->base, + RCANFD_GAFLECTR, RCANFD_GAFLECTR_AFLDAE); +} + +static void rcar_canfd_configure_rx(struct rcar_canfd_global *gpriv, u32 ch) +{ + /* Rx FIFO is used for reception */ + u32 cfg; + u16 rfdc, rfpls; + + /* Select Rx FIFO based on channel */ + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + rfdc = 2; /* b010 - 8 messages Rx FIFO depth */ + rfpls = 7; /* b111 - Max 64 bytes payload */ + + cfg = (RCANFD_RFCC_RFIM | RCANFD_RFCC_RFDC(rfdc) | + RCANFD_RFCC_RFPLS(rfpls) | RCANFD_RFCC_RFIE); + rcar_canfd_write(gpriv->base, RCANFD_RFCC(ridx), cfg); +} + +static void rcar_canfd_configure_tx(struct rcar_canfd_global *gpriv, u32 ch) +{ + /* Tx/Rx(Common) FIFO configured in Tx mode is + * used for transmission + * + * Each channel has 3 Common FIFO dedicated to them. + * Use the 1st (index 0) out of 3 + */ + u32 cfg; + u16 cftml, cfm, cfdc, cfpls; + + cftml = 0; /* 0th buffer */ + cfm = 1; /* b01 - Transmit mode */ + cfdc = 2; /* b010 - 8 messages Tx FIFO depth */ + cfpls = 7; /* b111 - Max 64 bytes payload */ + + cfg = (RCANFD_CFCC_CFTML(cftml) | RCANFD_CFCC_CFM(cfm) | + RCANFD_CFCC_CFIM | RCANFD_CFCC_CFDC(cfdc) | + RCANFD_CFCC_CFPLS(cfpls) | RCANFD_CFCC_CFTXIE); + rcar_canfd_write(gpriv->base, RCANFD_CFCC(ch, RCANFD_CFFIFO_IDX), cfg); + + /* Clear FD mode specific control/status register */ + rcar_canfd_write(gpriv->base, + RCANFD_F_CFFDCSTS(ch, RCANFD_CFFIFO_IDX), 0); +} + +static void rcar_canfd_enable_global_interrupts(struct rcar_canfd_global *gpriv) +{ + u32 ctr; + + /* Clear any stray error interrupt flags */ + rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0); + + /* Global interrupts setup */ + ctr = RCANFD_GCTR_MEIE; + ctr |= RCANFD_GCTR_CFMPOFIE; + + rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, ctr); +} + +static void rcar_canfd_disable_global_interrupts(struct rcar_canfd_global + *gpriv) +{ + /* Disable all interrupts */ + rcar_canfd_write(gpriv->base, RCANFD_GCTR, 0); + + /* Clear any stray error interrupt flags */ + rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0); +} + +static void rcar_canfd_enable_channel_interrupts(struct rcar_canfd_channel + *priv) +{ + u32 ctr, ch = priv->channel; + + /* Clear any stray error flags */ + rcar_canfd_write(priv->base, RCANFD_CERFL(ch), 0); + + /* Channel interrupts setup */ + ctr = (RCANFD_CCTR_TAIE | + RCANFD_CCTR_ALIE | RCANFD_CCTR_BLIE | + RCANFD_CCTR_OLIE | RCANFD_CCTR_BORIE | + RCANFD_CCTR_BOEIE | RCANFD_CCTR_EPIE | + RCANFD_CCTR_EWIE | RCANFD_CCTR_BEIE); + rcar_canfd_set_bit(priv->base, RCANFD_CCTR(ch), ctr); +} + +static void rcar_canfd_disable_channel_interrupts(struct rcar_canfd_channel + *priv) +{ + u32 ctr, ch = priv->channel; + + ctr = (RCANFD_CCTR_TAIE | + RCANFD_CCTR_ALIE | RCANFD_CCTR_BLIE | + RCANFD_CCTR_OLIE | RCANFD_CCTR_BORIE | + RCANFD_CCTR_BOEIE | RCANFD_CCTR_EPIE | + RCANFD_CCTR_EWIE | RCANFD_CCTR_BEIE); + rcar_canfd_clear_bit(priv->base, RCANFD_CCTR(ch), ctr); + + /* Clear any stray error flags */ + rcar_canfd_write(priv->base, RCANFD_CERFL(ch), 0); +} + +static void rcar_canfd_global_error(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + u32 ch = priv->channel; + u32 gerfl, sts; + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL); + if ((gerfl & RCANFD_GERFL_EEF0) && (ch == 0)) { + netdev_dbg(ndev, "Ch0: ECC Error flag\n"); + stats->tx_dropped++; + } + if ((gerfl & RCANFD_GERFL_EEF1) && (ch == 1)) { + netdev_dbg(ndev, "Ch1: ECC Error flag\n"); + stats->tx_dropped++; + } + if (gerfl & RCANFD_GERFL_MES) { + sts = rcar_canfd_read(priv->base, + RCANFD_CFSTS(ch, RCANFD_CFFIFO_IDX)); + if (sts & RCANFD_CFSTS_CFMLT) { + netdev_dbg(ndev, "Tx Message Lost flag\n"); + stats->tx_dropped++; + rcar_canfd_write(priv->base, + RCANFD_CFSTS(ch, RCANFD_CFFIFO_IDX), + sts & ~RCANFD_CFSTS_CFMLT); + } + + sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(ridx)); + if (sts & RCANFD_RFSTS_RFMLT) { + netdev_dbg(ndev, "Rx Message Lost flag\n"); + stats->rx_dropped++; + rcar_canfd_write(priv->base, RCANFD_RFSTS(ridx), + sts & ~RCANFD_RFSTS_RFMLT); + } + } + if (gerfl & RCANFD_GERFL_CMPOF) { + /* Message Lost flag will be set for respective channel + * when this condition happens with counters and flags + * already updated. + */ + netdev_dbg(ndev, "global payload overflow interrupt\n"); + } + + /* Clear all global error interrupts. Only affected channels bits + * get cleared + */ + rcar_canfd_write(priv->base, RCANFD_GERFL, 0); +} + +static void rcar_canfd_error(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf; + struct sk_buff *skb; + u32 cerfl, csts; + u32 txerr = 0, rxerr = 0; + u32 ch = priv->channel; + + /* Propagate the error condition to the CAN stack */ + skb = alloc_can_err_skb(ndev, &cf); + if (!skb) { + stats->rx_dropped++; + return; + } + + /* Channel error interrupt */ + cerfl = rcar_canfd_read(priv->base, RCANFD_CERFL(ch)); + csts = rcar_canfd_read(priv->base, RCANFD_CSTS(ch)); + txerr = RCANFD_CSTS_TECCNT(csts); + rxerr = RCANFD_CSTS_RECCNT(csts); + + netdev_dbg(ndev, "ch erfl %x sts %x txerr %u rxerr %u\n", + cerfl, csts, txerr, rxerr); + + if (cerfl & RCANFD_CERFL_BEF) { + netdev_dbg(ndev, "Bus error\n"); + cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; + cf->data[2] = CAN_ERR_PROT_UNSPEC; + priv->can.can_stats.bus_error++; + } + if (cerfl & RCANFD_CERFL_ADERR) { + netdev_dbg(ndev, "ACK Delimiter Error\n"); + stats->tx_errors++; + cf->data[3] |= CAN_ERR_PROT_LOC_ACK_DEL; + } + if (cerfl & RCANFD_CERFL_B0ERR) { + netdev_dbg(ndev, "Bit Error (dominant)\n"); + stats->tx_errors++; + cf->data[2] |= CAN_ERR_PROT_BIT0; + } + if (cerfl & RCANFD_CERFL_B1ERR) { + netdev_dbg(ndev, "Bit Error (recessive)\n"); + stats->tx_errors++; + cf->data[2] |= CAN_ERR_PROT_BIT1; + } + if (cerfl & RCANFD_CERFL_CERR) { + netdev_dbg(ndev, "CRC Error\n"); + stats->rx_errors++; + cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; + } + if (cerfl & RCANFD_CERFL_AERR) { + netdev_dbg(ndev, "ACK Error\n"); + stats->tx_errors++; + cf->can_id |= CAN_ERR_ACK; + cf->data[3] |= CAN_ERR_PROT_LOC_ACK; + } + if (cerfl & RCANFD_CERFL_FERR) { + netdev_dbg(ndev, "Form Error\n"); + stats->rx_errors++; + cf->data[2] |= CAN_ERR_PROT_FORM; + } + if (cerfl & RCANFD_CERFL_SERR) { + netdev_dbg(ndev, "Stuff Error\n"); + stats->rx_errors++; + cf->data[2] |= CAN_ERR_PROT_STUFF; + } + if (cerfl & RCANFD_CERFL_ALF) { + netdev_dbg(ndev, "Arbitration lost Error\n"); + priv->can.can_stats.arbitration_lost++; + cf->can_id |= CAN_ERR_LOSTARB; + cf->data[0] |= CAN_ERR_LOSTARB_UNSPEC; + } + if (cerfl & RCANFD_CERFL_BLF) { + netdev_dbg(ndev, "Bus Lock Error\n"); + stats->rx_errors++; + cf->can_id |= CAN_ERR_BUSERROR; + } + if (cerfl & RCANFD_CERFL_EWF) { + netdev_dbg(ndev, "Error warning interrupt\n"); + priv->can.state = CAN_STATE_ERROR_WARNING; + priv->can.can_stats.error_warning++; + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING : + CAN_ERR_CRTL_RX_WARNING; + cf->data[6] = txerr; + cf->data[7] = rxerr; + } + if (cerfl & RCANFD_CERFL_EPF) { + netdev_dbg(ndev, "Error passive interrupt\n"); + priv->can.state = CAN_STATE_ERROR_PASSIVE; + priv->can.can_stats.error_passive++; + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE : + CAN_ERR_CRTL_RX_PASSIVE; + cf->data[6] = txerr; + cf->data[7] = rxerr; + } + if (cerfl & RCANFD_CERFL_BOEF) { + netdev_dbg(ndev, "Bus-off entry interrupt\n"); + rcar_canfd_tx_failure_cleanup(ndev); + priv->can.state = CAN_STATE_BUS_OFF; + priv->can.can_stats.bus_off++; + can_bus_off(ndev); + cf->can_id |= CAN_ERR_BUSOFF; + } + if (cerfl & RCANFD_CERFL_OVLF) { + netdev_dbg(ndev, + "Overload Frame Transmission error interrupt\n"); + stats->tx_errors++; + cf->can_id |= CAN_ERR_PROT; + cf->data[2] |= CAN_ERR_PROT_OVERLOAD; + } + + /* Clear all channel error interrupts */ + rcar_canfd_write(priv->base, RCANFD_CERFL(ch), 0); + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + netif_rx(skb); +} + +static void rcar_canfd_tx_done(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + u32 sts; + unsigned long flags; + u32 ch = priv->channel; + + do { + u8 unsent, sent; + + sent = priv->tx_tail % RCANFD_FIFO_DEPTH; + stats->tx_packets++; + stats->tx_bytes += priv->tx_len[sent]; + priv->tx_len[sent] = 0; + can_get_echo_skb(ndev, sent); + + spin_lock_irqsave(&priv->tx_lock, flags); + priv->tx_tail++; + sts = rcar_canfd_read(priv->base, + RCANFD_CFSTS(ch, RCANFD_CFFIFO_IDX)); + unsent = RCANFD_CFSTS_CFMC(sts); + + /* Wake producer only when there is room */ + if (unsent != RCANFD_FIFO_DEPTH) + netif_wake_queue(ndev); + + if (priv->tx_head - priv->tx_tail <= unsent) { + spin_unlock_irqrestore(&priv->tx_lock, flags); + break; + } + spin_unlock_irqrestore(&priv->tx_lock, flags); + + } while (1); + + /* Clear interrupt */ + rcar_canfd_write(priv->base, RCANFD_CFSTS(ch, RCANFD_CFFIFO_IDX), + sts & ~RCANFD_CFSTS_CFTXIF); + can_led_event(ndev, CAN_LED_EVENT_TX); +} + +static irqreturn_t rcar_canfd_global_interrupt(int irq, void *dev_id) +{ + struct rcar_canfd_global *gpriv = dev_id; + struct net_device *ndev; + struct rcar_canfd_channel *priv; + u32 sts, gerfl; + u32 ch, ridx; + + /* Global error interrupts still indicate a condition specific + * to a channel. RxFIFO interrupt is a global interrupt. + */ + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + priv = gpriv->ch[ch]; + ndev = priv->ndev; + ridx = ch + RCANFD_RFFIFO_IDX; + + /* Global error interrupts */ + gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL); + if (RCANFD_GERFL_ERR(gerfl)) + rcar_canfd_global_error(ndev); + + /* Handle Rx interrupts */ + sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(ridx)); + if (sts & RCANFD_RFSTS_RFIF) { + if (napi_schedule_prep(&priv->napi)) { + /* Disable Rx FIFO interrupts */ + rcar_canfd_clear_bit(priv->base, + RCANFD_RFCC(ridx), + RCANFD_RFCC_RFIE); + __napi_schedule(&priv->napi); + } + } + } + return IRQ_HANDLED; +} + +static irqreturn_t rcar_canfd_channel_interrupt(int irq, void *dev_id) +{ + struct rcar_canfd_global *gpriv = dev_id; + struct net_device *ndev; + struct rcar_canfd_channel *priv; + u32 sts, cerfl, ch; + + /* Common FIFO is a per channel resource */ + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + priv = gpriv->ch[ch]; + ndev = priv->ndev; + + /* Channel error interrupts */ + cerfl = rcar_canfd_read(priv->base, RCANFD_CERFL(ch)); + if (RCANFD_CERFL_ERR(cerfl)) + rcar_canfd_error(ndev); + + /* Handle Tx interrupts */ + sts = rcar_canfd_read(priv->base, + RCANFD_CFSTS(ch, RCANFD_CFFIFO_IDX)); + if (sts & RCANFD_CFSTS_CFTXIF) + rcar_canfd_tx_done(ndev); + } + return IRQ_HANDLED; +} + +static void rcar_canfd_set_bittiming(struct net_device *dev) +{ + struct rcar_canfd_channel *priv = netdev_priv(dev); + const struct can_bittiming *bt = &priv->can.bittiming; + const struct can_bittiming *dbt = &priv->can.data_bittiming; + u16 brp, sjw, tseg1, tseg2; + u32 cfg; + u32 ch = priv->channel; + + /* Nominal bit timing settings */ + brp = bt->brp - 1; + sjw = bt->sjw - 1; + tseg1 = bt->prop_seg + bt->phase_seg1 - 1; + tseg2 = bt->phase_seg2 - 1; + + cfg = (RCANFD_NCFG_NTSEG1(tseg1) | RCANFD_NCFG_NBRP(brp) | + RCANFD_NCFG_NSJW(sjw) | RCANFD_NCFG_NTSEG2(tseg2)); + + rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg); + netdev_dbg(priv->ndev, "nrate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", + brp, sjw, tseg1, tseg2); + + /* Data bit timing settings */ + brp = dbt->brp - 1; + sjw = dbt->sjw - 1; + tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; + tseg2 = dbt->phase_seg2 - 1; + + cfg = (RCANFD_DCFG_DTSEG1(tseg1) | RCANFD_DCFG_DBRP(brp) | + RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(tseg2)); + + rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg); + netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", + brp, sjw, tseg1, tseg2); +} + +static int rcar_canfd_start(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + int err = -EOPNOTSUPP; + u32 sts, ch = priv->channel; + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + rcar_canfd_set_bittiming(ndev); + + rcar_canfd_enable_channel_interrupts(priv); + + /* Set channel to Operational mode */ + rcar_canfd_update_bit(priv->base, RCANFD_CCTR(ch), + RCANFD_CCTR_CHMDC_MASK, RCANFD_CCTR_CHDMC_COPM); + + /* Verify channel mode change */ + err = readl_poll_timeout((priv->base + RCANFD_CSTS(ch)), sts, + (sts & RCANFD_CSTS_COMSTS), 2, 500000); + if (err) { + netdev_err(ndev, "channel %u communication state failed\n", ch); + goto fail_mode_change; + } + + /* Enable Common & Rx FIFO */ + rcar_canfd_set_bit(priv->base, RCANFD_CFCC(ch, RCANFD_CFFIFO_IDX), + RCANFD_CFCC_CFE); + rcar_canfd_set_bit(priv->base, RCANFD_RFCC(ridx), RCANFD_RFCC_RFE); + + priv->can.state = CAN_STATE_ERROR_ACTIVE; + return 0; + +fail_mode_change: + rcar_canfd_disable_channel_interrupts(priv); + return err; +} + +static int rcar_canfd_open(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct rcar_canfd_global *gpriv = priv->gpriv; + int err; + + /* Peripheral clock is already enabled in probe */ + err = clk_prepare_enable(gpriv->can_clk); + if (err) { + netdev_err(ndev, "failed to enable CAN clock, error %d\n", err); + goto out_clock; + } + + err = open_candev(ndev); + if (err) { + netdev_err(ndev, "open_candev() failed, error %d\n", err); + goto out_can_clock; + } + + napi_enable(&priv->napi); + err = rcar_canfd_start(ndev); + if (err) + goto out_close; + netif_start_queue(ndev); + can_led_event(ndev, CAN_LED_EVENT_OPEN); + return 0; +out_close: + napi_disable(&priv->napi); + close_candev(ndev); +out_can_clock: + clk_disable_unprepare(gpriv->can_clk); +out_clock: + return err; +} + +static void rcar_canfd_stop(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + int err; + u32 sts, ch = priv->channel; + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + /* Transition to channel reset mode */ + rcar_canfd_update_bit(priv->base, RCANFD_CCTR(ch), + RCANFD_CCTR_CHMDC_MASK, RCANFD_CCTR_CHDMC_CRESET); + + /* Check Channel reset mode */ + err = readl_poll_timeout((priv->base + RCANFD_CSTS(ch)), sts, + (sts & RCANFD_CSTS_CRSTSTS), 2, 500000); + if (err) + netdev_err(ndev, "channel %u reset failed\n", ch); + + rcar_canfd_disable_channel_interrupts(priv); + + /* Disable Common & Rx FIFO */ + rcar_canfd_clear_bit(priv->base, RCANFD_CFCC(ch, RCANFD_CFFIFO_IDX), + RCANFD_CFCC_CFE); + rcar_canfd_clear_bit(priv->base, RCANFD_RFCC(ridx), RCANFD_RFCC_RFE); + + /* Set the state as STOPPED */ + priv->can.state = CAN_STATE_STOPPED; +} + +static int rcar_canfd_close(struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct rcar_canfd_global *gpriv = priv->gpriv; + + netif_stop_queue(ndev); + rcar_canfd_stop(ndev); + napi_disable(&priv->napi); + clk_disable_unprepare(gpriv->can_clk); + close_candev(ndev); + can_led_event(ndev, CAN_LED_EVENT_STOP); + return 0; +} + +static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb, + struct net_device *ndev) +{ + struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct canfd_frame *cf = (struct canfd_frame *)skb->data; + u32 sts = 0, id, dlc; + unsigned long flags; + u32 ch = priv->channel; + + if (can_dropped_invalid_skb(ndev, skb)) + return NETDEV_TX_OK; + + if (cf->can_id & CAN_EFF_FLAG) { + id = cf->can_id & CAN_EFF_MASK; + id |= RCANFD_CFID_CFIDE; + } else { + id = cf->can_id & CAN_SFF_MASK; + } + + if (cf->can_id & CAN_RTR_FLAG) + id |= RCANFD_CFID_CFRTR; + + rcar_canfd_write(priv->base, + RCANFD_F_CFID(ch, RCANFD_CFFIFO_IDX), id); + dlc = RCANFD_CFPTR_CFDLC(can_len2dlc(cf->len)); + rcar_canfd_write(priv->base, + RCANFD_F_CFPTR(ch, RCANFD_CFFIFO_IDX), dlc); + + if (can_is_canfd_skb(skb)) { + /* CAN FD frame format */ + sts |= RCANFD_CFFDCSTS_CFFDF; + if (cf->flags & CANFD_BRS) + sts |= RCANFD_CFFDCSTS_CFBRS; + + if (priv->can.state == CAN_STATE_ERROR_PASSIVE) + sts |= RCANFD_CFFDCSTS_CFESI; + } + + rcar_canfd_write(priv->base, RCANFD_F_CFFDCSTS(ch, RCANFD_CFFIFO_IDX), + sts); + + rcar_canfd_put_data(priv, cf, + RCANFD_F_CFDF(ch, RCANFD_CFFIFO_IDX, 0)); + + priv->tx_len[priv->tx_head % RCANFD_FIFO_DEPTH] = cf->len; + can_put_echo_skb(skb, ndev, priv->tx_head % RCANFD_FIFO_DEPTH); + + spin_lock_irqsave(&priv->tx_lock, flags); + priv->tx_head++; + + /* Stop the queue if we've filled all FIFO entries */ + if (priv->tx_head - priv->tx_tail >= RCANFD_FIFO_DEPTH) + netif_stop_queue(ndev); + + /* Start Tx: Write 0xff to CFPC to increment the CPU-side + * pointer for the Common FIFO + */ + rcar_canfd_write(priv->base, + RCANFD_CFPCTR(ch, RCANFD_CFFIFO_IDX), 0xff); + + spin_unlock_irqrestore(&priv->tx_lock, flags); + return NETDEV_TX_OK; +} + +static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv) +{ + struct net_device_stats *stats = &priv->ndev->stats; + struct canfd_frame *cf; + struct sk_buff *skb; + u32 sts = 0, id, ptr; + u32 ch = priv->channel; + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + id = rcar_canfd_read(priv->base, RCANFD_F_RFID(ridx)); + ptr = rcar_canfd_read(priv->base, RCANFD_F_RFPTR(ridx)); + + sts = rcar_canfd_read(priv->base, RCANFD_F_RFFDSTS(ridx)); + if (sts & RCANFD_RFFDSTS_RFFDF) + skb = alloc_canfd_skb(priv->ndev, &cf); + else + skb = alloc_can_skb(priv->ndev, + (struct can_frame **)&cf); + + if (!skb) { + stats->rx_dropped++; + return; + } + + if (sts & RCANFD_RFFDSTS_RFFDF) + cf->len = can_dlc2len(RCANFD_RFPTR_RFDLC(ptr)); + else + cf->len = get_can_dlc(RCANFD_RFPTR_RFDLC(ptr)); + + if (sts & RCANFD_RFFDSTS_RFESI) { + cf->flags |= CANFD_ESI; + netdev_dbg(priv->ndev, "ESI Error\n"); + } + + if (id & RCANFD_RFID_RFIDE) + cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; + else + cf->can_id = id & CAN_SFF_MASK; + + if (!(sts & RCANFD_RFFDSTS_RFFDF) && (id & RCANFD_RFID_RFRTR)) { + cf->can_id |= CAN_RTR_FLAG; + } else { + if (sts & RCANFD_RFFDSTS_RFBRS) + cf->flags |= CANFD_BRS; + + rcar_canfd_get_data(priv, cf, RCANFD_F_RFDF(ridx, 0)); + } + + /* Write 0xff to RFPC to increment the CPU-side + * pointer of the Rx FIFO + */ + rcar_canfd_write(priv->base, RCANFD_RFPCTR(ridx), 0xff); + + can_led_event(priv->ndev, CAN_LED_EVENT_RX); + + stats->rx_bytes += cf->len; + stats->rx_packets++; + netif_receive_skb(skb); +} + +static int rcar_canfd_rx_poll(struct napi_struct *napi, int quota) +{ + struct rcar_canfd_channel *priv = + container_of(napi, struct rcar_canfd_channel, napi); + int num_pkts; + u32 sts; + u32 ch = priv->channel; + u32 ridx = ch + RCANFD_RFFIFO_IDX; + + for (num_pkts = 0; num_pkts < quota; num_pkts++) { + sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(ridx)); + /* Check FIFO empty condition */ + if (sts & RCANFD_RFSTS_RFEMP) + break; + + rcar_canfd_rx_pkt(priv); + + /* Clear interrupt bit */ + if (sts & RCANFD_RFSTS_RFIF) + rcar_canfd_write(priv->base, RCANFD_RFSTS(ridx), + sts & ~RCANFD_RFSTS_RFIF); + } + + /* All packets processed */ + if (num_pkts < quota) { + napi_complete(napi); + /* Enable Rx FIFO interrupts */ + rcar_canfd_set_bit(priv->base, RCANFD_RFCC(ridx), + RCANFD_RFCC_RFIE); + } + return num_pkts; +} + +static int rcar_canfd_do_set_mode(struct net_device *ndev, enum can_mode mode) +{ + int err; + + switch (mode) { + case CAN_MODE_START: + err = rcar_canfd_start(ndev); + if (err) + return err; + netif_wake_queue(ndev); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int rcar_canfd_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct rcar_canfd_channel *priv = netdev_priv(dev); + u32 val, ch = priv->channel; + + /* Peripheral clock is already enabled in probe */ + val = rcar_canfd_read(priv->base, RCANFD_CSTS(ch)); + bec->txerr = RCANFD_CSTS_TECCNT(val); + bec->rxerr = RCANFD_CSTS_RECCNT(val); + return 0; +} + +static const struct net_device_ops rcar_canfd_netdev_ops = { + .ndo_open = rcar_canfd_open, + .ndo_stop = rcar_canfd_close, + .ndo_start_xmit = rcar_canfd_start_xmit, + .ndo_change_mtu = can_change_mtu, +}; + +static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, + u32 fcan_freq) +{ + struct platform_device *pdev = gpriv->pdev; + struct rcar_canfd_channel *priv; + struct net_device *ndev; + int err = -ENODEV; + + ndev = alloc_candev(sizeof(*priv), RCANFD_FIFO_DEPTH); + if (!ndev) { + dev_err(&pdev->dev, "alloc_candev() failed\n"); + err = -ENOMEM; + goto fail; + } + priv = netdev_priv(ndev); + + ndev->netdev_ops = &rcar_canfd_netdev_ops; + ndev->flags |= IFF_ECHO; + priv->ndev = ndev; + priv->base = gpriv->base; + priv->channel = ch; + priv->can.clock.freq = fcan_freq; + dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq); + + priv->can.bittiming_const = &rcar_canfd_nom_bittiming_const; + priv->can.data_bittiming_const = + &rcar_canfd_data_bittiming_const; + + /* Controller starts in CAN FD only mode */ + can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD); + priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING; + + priv->can.do_set_mode = rcar_canfd_do_set_mode; + priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter; + priv->gpriv = gpriv; + SET_NETDEV_DEV(ndev, &pdev->dev); + + netif_napi_add(ndev, &priv->napi, rcar_canfd_rx_poll, + RCANFD_NAPI_WEIGHT); + err = register_candev(ndev); + if (err) { + dev_err(&pdev->dev, + "register_candev() failed, error %d\n", err); + goto fail_candev; + } + spin_lock_init(&priv->tx_lock); + devm_can_led_init(ndev); + gpriv->ch[priv->channel] = priv; + dev_info(&pdev->dev, "device registered (channel %u)\n", priv->channel); + return 0; + +fail_candev: + netif_napi_del(&priv->napi); + free_candev(ndev); +fail: + return err; +} + +static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch) +{ + struct rcar_canfd_channel *priv = gpriv->ch[ch]; + + if (priv) { + unregister_candev(priv->ndev); + netif_napi_del(&priv->napi); + free_candev(priv->ndev); + } +} + +static int rcar_canfd_probe(struct platform_device *pdev) +{ + struct resource *mem; + void __iomem *addr; + u32 sts, ch, fcan_freq; + struct rcar_canfd_global *gpriv; + struct device_node *of_child; + unsigned long channels_mask = 0; + int err, ch_irq, g_irq; + + of_child = of_get_child_by_name(pdev->dev.of_node, "channel0"); + if (of_child && of_device_is_available(of_child)) + channels_mask |= BIT(0); /* Channel 0 */ + + of_child = of_get_child_by_name(pdev->dev.of_node, "channel1"); + if (of_child && of_device_is_available(of_child)) + channels_mask |= BIT(1); /* Channel 1 */ + + ch_irq = platform_get_irq(pdev, 0); + if (ch_irq < 0) { + dev_err(&pdev->dev, "no Channel IRQ resource\n"); + err = ch_irq; + goto fail_dev; + } + + g_irq = platform_get_irq(pdev, 1); + if (g_irq < 0) { + dev_err(&pdev->dev, "no Global IRQ resource\n"); + err = g_irq; + goto fail_dev; + } + + /* Global controller context */ + gpriv = devm_kzalloc(&pdev->dev, sizeof(*gpriv), GFP_KERNEL); + if (!gpriv) { + err = -ENOMEM; + goto fail_dev; + } + gpriv->pdev = pdev; + gpriv->channels_mask = channels_mask; + + /* Peripheral clock */ + gpriv->clkp = devm_clk_get(&pdev->dev, "fck"); + if (IS_ERR(gpriv->clkp)) { + err = PTR_ERR(gpriv->clkp); + dev_err(&pdev->dev, "cannot get peripheral clock, error %d\n", + err); + goto fail_dev; + } + + /* fCAN clock: Pick External clock. If not available fallback to + * CANFD clock + */ + gpriv->can_clk = devm_clk_get(&pdev->dev, "can_clk"); + if (IS_ERR(gpriv->can_clk) || (clk_get_rate(gpriv->can_clk) == 0)) { + gpriv->can_clk = devm_clk_get(&pdev->dev, "canfd"); + if (IS_ERR(gpriv->can_clk)) { + err = PTR_ERR(gpriv->can_clk); + dev_err(&pdev->dev, + "cannot get canfd clock, error %d\n", err); + goto fail_dev; + } + gpriv->fcan = RCANFD_CANFDCLK; + + } else { + gpriv->fcan = RCANFD_EXTCLK; + } + fcan_freq = clk_get_rate(gpriv->can_clk); + + if (gpriv->fcan == RCANFD_CANFDCLK) + /* CANFD clock is further divided by (1/2) within the IP */ + fcan_freq /= 2; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + addr = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(addr)) { + err = PTR_ERR(addr); + goto fail_dev; + } + gpriv->base = addr; + + /* Request IRQ that's common for both channels */ + err = devm_request_irq(&pdev->dev, ch_irq, + rcar_canfd_channel_interrupt, 0, + "canfd.chn", gpriv); + if (err) { + dev_err(&pdev->dev, "devm_request_irq(%d) failed, error %d\n", + ch_irq, err); + goto fail_dev; + } + err = devm_request_irq(&pdev->dev, g_irq, + rcar_canfd_global_interrupt, 0, + "canfd.gbl", gpriv); + if (err) { + dev_err(&pdev->dev, "devm_request_irq(%d) failed, error %d\n", + g_irq, err); + goto fail_dev; + } + + /* Enable peripheral clock for register access */ + err = clk_prepare_enable(gpriv->clkp); + if (err) { + dev_err(&pdev->dev, + "failed to enable peripheral clock, error %d\n", err); + goto fail_dev; + } + + err = rcar_canfd_reset_controller(gpriv); + if (err) { + dev_err(&pdev->dev, "reset controller failed\n"); + goto fail_clk; + } + + /* Controller in Global reset & Channel reset mode */ + rcar_canfd_configure_controller(gpriv); + + /* Configure per channel attributes */ + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + /* Configure Channel's Rx fifo */ + rcar_canfd_configure_rx(gpriv, ch); + + /* Configure Channel's Tx (Common) fifo */ + rcar_canfd_configure_tx(gpriv, ch); + + /* Configure receive rules */ + rcar_canfd_configure_afl_rules(gpriv, ch); + } + + /* Configure common interrupts */ + rcar_canfd_enable_global_interrupts(gpriv); + + /* Start Global operation mode */ + rcar_canfd_update_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GMDC_MASK, + RCANFD_GCTR_GMDC_GOPM); + + /* Verify mode change */ + err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts, + !(sts & RCANFD_GSTS_GNOPM), 2, 500000); + if (err) { + dev_err(&pdev->dev, "global operational mode failed\n"); + goto fail_mode; + } + + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq); + if (err) + goto fail_channel; + } + + platform_set_drvdata(pdev, gpriv); + dev_info(&pdev->dev, "global operational state (clk %d)\n", + gpriv->fcan); + return 0; + +fail_channel: + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) + rcar_canfd_channel_remove(gpriv, ch); +fail_mode: + rcar_canfd_disable_global_interrupts(gpriv); +fail_clk: + clk_disable_unprepare(gpriv->clkp); +fail_dev: + return err; +} + +static int rcar_canfd_remove(struct platform_device *pdev) +{ + struct rcar_canfd_global *gpriv = platform_get_drvdata(pdev); + u32 ch; + + rcar_canfd_reset_controller(gpriv); + rcar_canfd_disable_global_interrupts(gpriv); + + for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { + rcar_canfd_disable_channel_interrupts(gpriv->ch[ch]); + rcar_canfd_channel_remove(gpriv, ch); + } + + /* Enter global sleep mode */ + rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR); + clk_disable_unprepare(gpriv->clkp); + return 0; +} + +static int __maybe_unused rcar_canfd_suspend(struct device *dev) +{ + return 0; +} + +static int __maybe_unused rcar_canfd_resume(struct device *dev) +{ + return 0; +} + +static SIMPLE_DEV_PM_OPS(rcar_canfd_pm_ops, rcar_canfd_suspend, + rcar_canfd_resume); + +static const struct of_device_id rcar_canfd_of_table[] = { + { .compatible = "renesas,rcar-gen3-canfd" }, + { } +}; + +MODULE_DEVICE_TABLE(of, rcar_canfd_of_table); + +static struct platform_driver rcar_canfd_driver = { + .driver = { + .name = RCANFD_DRV_NAME, + .of_match_table = of_match_ptr(rcar_canfd_of_table), + .pm = &rcar_canfd_pm_ops, + }, + .probe = rcar_canfd_probe, + .remove = rcar_canfd_remove, +}; + +module_platform_driver(rcar_canfd_driver); + +MODULE_AUTHOR("Ramesh Shanmugasundaram "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CAN FD driver for Renesas R-Car SoC"); +MODULE_ALIAS("platform:" RCANFD_DRV_NAME); -- cgit v1.3-14-g43fede From 2562756dde550901c224e3805102bdfc17e7d13a Mon Sep 17 00:00:00 2001 From: Masaki Ota Date: Thu, 16 Jun 2016 18:45:57 +0900 Subject: HID: add Alps I2C HID Touchpad-Stick support Add support Alps I2C HID Touchpad and Stick device. Signed-off-by: Masaki Ota Signed-off-by: Jiri Kosina --- Documentation/hid/hid-alps.txt | 139 +++++++++++ drivers/hid/Kconfig | 8 + drivers/hid/Makefile | 1 + drivers/hid/hid-alps.c | 525 +++++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-ids.h | 2 + 5 files changed, 675 insertions(+) create mode 100644 Documentation/hid/hid-alps.txt create mode 100644 drivers/hid/hid-alps.c (limited to 'Documentation') diff --git a/Documentation/hid/hid-alps.txt b/Documentation/hid/hid-alps.txt new file mode 100644 index 000000000000..6b02a2447c77 --- /dev/null +++ b/Documentation/hid/hid-alps.txt @@ -0,0 +1,139 @@ +ALPS HID Touchpad Protocol +---------------------- + +Introduction +------------ +Currently ALPS HID driver supports U1 Touchpad device. + +U1 devuce basic information. +Vender ID 0x044E +Product ID 0x120B +Version ID 0x0121 + + +HID Descriptor +------------ +Byte Field Value Notes +0 wHIDDescLength 001E Length of HID Descriptor : 30 bytes +2 bcdVersion 0100 Compliant with Version 1.00 +4 wReportDescLength 00B2 Report Descriptor is 178 Bytes (0x00B2) +6 wReportDescRegister 0002 Identifier to read Report Descriptor +8 wInputRegister 0003 Identifier to read Input Report +10 wMaxInputLength 0053 Input Report is 80 Bytes + 2 +12 wOutputRegister 0000 Identifier to read Output Report +14 wMaxOutputLength 0000 No Output Reports +16 wCommandRegister 0005 Identifier for Command Register +18 wDataRegister 0006 Identifier for Data Register +20 wVendorID 044E Vendor ID 0x044E +22 wProductID 120B Product ID 0x120B +24 wVersionID 0121 Version 01.21 +26 RESERVED 0000 RESERVED + + +Report ID +------------ +ReportID-1 (Input Reports) (HIDUsage-Mouse) for TP&SP +ReportID-2 (Input Reports) (HIDUsage-keyboard) for TP +ReportID-3 (Input Reports) (Vendor Usage: Max 10 finger data) for TP +ReportID-4 (Input Reports) (Vendor Usage: ON bit data) for GP +ReportID-5 (Feature Reports) Feature Reports +ReportID-6 (Input Reports) (Vendor Usage: StickPointer data) for SP +ReportID-7 (Feature Reports) Flash update (Bootloader) + + +Data pattern +------------ +Case1 ReportID_1 TP/SP Relative/Relative +Case2 ReportID_3 TP Absolute + ReportID_6 SP Absolute + + +Command Read/Write +------------------ +To read/write to RAM, need to send a commands to the device. +The command format is as below. + +DataByte(SET_REPORT) +Byte1 Command Byte +Byte2 Address - Byte 0 (LSB) +Byte3 Address - Byte 1 +Byte4 Address - Byte 2 +Byte5 Address - Byte 3 (MSB) +Byte6 Value Byte +Byte7 Checksum + +Command Byte is read=0xD1/write=0xD2 . +Address is read/write RAM address. +Value Byte is writing data when you send the write commands. +When you read RAM, there is no meaning. + +DataByte(GET_REPORT) +Byte1 Response Byte +Byte2 Address - Byte 0 (LSB) +Byte3 Address - Byte 1 +Byte4 Address - Byte 2 +Byte5 Address - Byte 3 (MSB) +Byte6 Value Byte +Byte7 Checksum + +Read value is stored in Value Byte. + + +Packet Format +Touchpad data byte +------------------ + b7 b6 b5 b4 b3 b2 b1 b0 +1 0 0 SW6 SW5 SW4 SW3 SW2 SW1 +2 0 0 0 Fcv Fn3 Fn2 Fn1 Fn0 +3 Xa0_7 Xa0_6 Xa0_5 Xa0_4 Xa0_3 Xa0_2 Xa0_1 Xa0_0 +4 Xa0_15 Xa0_14 Xa0_13 Xa0_12 Xa0_11 Xa0_10 Xa0_9 Xa0_8 +5 Ya0_7 Ya0_6 Ya0_5 Ya0_4 Ya0_3 Ya0_2 Ya0_1 Ya0_0 +6 Ya0_15 Ya0_14 Ya0_13 Ya0_12 Ya0_11 Ya0_10 Ya0_9 Ya0_8 +7 LFB0 Zs0_6 Zs0_5 Zs0_4 Zs0_3 Zs0_2 Zs0_1 Zs0_0 + +8 Xa1_7 Xa1_6 Xa1_5 Xa1_4 Xa1_3 Xa1_2 Xa1_1 Xa1_0 +9 Xa1_15 Xa1_14 Xa1_13 Xa1_12 Xa1_11 Xa1_10 Xa1_9 Xa1_8 +10 Ya1_7 Ya1_6 Ya1_5 Ya1_4 Ya1_3 Ya1_2 Ya1_1 Ya1_0 +11 Ya1_15 Ya1_14 Ya1_13 Ya1_12 Ya1_11 Ya1_10 Ya1_9 Ya1_8 +12 LFB1 Zs1_6 Zs1_5 Zs1_4 Zs1_3 Zs1_2 Zs1_1 Zs1_0 + +13 Xa2_7 Xa2_6 Xa2_5 Xa2_4 Xa2_3 Xa2_2 Xa2_1 Xa2_0 +14 Xa2_15 Xa2_14 Xa2_13 Xa2_12 Xa2_11 Xa2_10 Xa2_9 Xa2_8 +15 Ya2_7 Ya2_6 Ya2_5 Ya2_4 Ya2_3 Ya2_2 Ya2_1 Ya2_0 +16 Ya2_15 Ya2_14 Ya2_13 Ya2_12 Ya2_11 Ya2_10 Ya2_9 Ya2_8 +17 LFB2 Zs2_6 Zs2_5 Zs2_4 Zs2_3 Zs2_2 Zs2_1 Zs2_0 + +18 Xa3_7 Xa3_6 Xa3_5 Xa3_4 Xa3_3 Xa3_2 Xa3_1 Xa3_0 +19 Xa3_15 Xa3_14 Xa3_13 Xa3_12 Xa3_11 Xa3_10 Xa3_9 Xa3_8 +20 Ya3_7 Ya3_6 Ya3_5 Ya3_4 Ya3_3 Ya3_2 Ya3_1 Ya3_0 +21 Ya3_15 Ya3_14 Ya3_13 Ya3_12 Ya3_11 Ya3_10 Ya3_9 Ya3_8 +22 LFB3 Zs3_6 Zs3_5 Zs3_4 Zs3_3 Zs3_2 Zs3_1 Zs3_0 + +23 Xa4_7 Xa4_6 Xa4_5 Xa4_4 Xa4_3 Xa4_2 Xa4_1 Xa4_0 +24 Xa4_15 Xa4_14 Xa4_13 Xa4_12 Xa4_11 Xa4_10 Xa4_9 Xa4_8 +25 Ya4_7 Ya4_6 Ya4_5 Ya4_4 Ya4_3 Ya4_2 Ya4_1 Ya4_0 +26 Ya4_15 Ya4_14 Ya4_13 Ya4_12 Ya4_11 Ya4_10 Ya4_9 Ya4_8 +27 LFB4 Zs4_6 Zs4_5 Zs4_4 Zs4_3 Zs4_2 Zs4_1 Zs4_0 + + +SW1-SW6: SW ON/OFF status +Xan_15-0(16bit):X Absolute data of the "n"th finger +Yan_15-0(16bit):Y Absolute data of the "n"th finger +Zsn_6-0(7bit): Operation area of the "n"th finger + + +StickPointer data byte +------------------ + b7 b6 b5 b4 b3 b2 b1 b0 +Byte1 1 1 1 0 1 SW3 SW2 SW1 +Byte2 X7 X6 X5 X4 X3 X2 X1 X0 +Byte3 X15 X14 X13 X12 X11 X10 X9 X8 +Byte4 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 +Byte5 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8 +Byte6 Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 +Byte7 T&P Z14 Z13 Z12 Z11 Z10 Z9 Z8 + +SW1-SW3: SW ON/OFF status +Xn_15-0(16bit):X Absolute data +Yn_15-0(16bit):Y Absolute data +Zn_14-0(15bit):Z diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 5646ca4b95de..a8e480849a32 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -936,6 +936,14 @@ config HID_SENSOR_CUSTOM_SENSOR standard sensors. Select this config option for custom/generic sensor support. +config HID_ALPS + tristate "Alps HID device support" + depends on HID + ---help--- + Support for Alps I2C HID touchpads and StickPointer. + Say Y here if you have a Alps touchpads over i2c-hid or usbhid + and want support for its special functionalities. + endmenu endif # HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index a2fb562de748..a55ec2988d38 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -21,6 +21,7 @@ hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o hid-wiimote-$(CONFIG_DEBUG_FS) += hid-wiimote-debug.o obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o +obj-$(CONFIG_HID_ALPS) += hid-alps.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c new file mode 100644 index 000000000000..b79c318987a3 --- /dev/null +++ b/drivers/hid/hid-alps.c @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2016 Masaki Ota + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include "hid-ids.h" + +/* ALPS Device Product ID */ +#define HID_PRODUCT_ID_T3_BTNLESS 0xD0C0 +#define HID_PRODUCT_ID_COSMO 0x1202 +#define HID_PRODUCT_ID_U1_PTP_1 0x1207 +#define HID_PRODUCT_ID_U1 0x1209 +#define HID_PRODUCT_ID_U1_PTP_2 0x120A +#define HID_PRODUCT_ID_U1_DUAL 0x120B +#define HID_PRODUCT_ID_T4_BTNLESS 0x120C + +#define DEV_SINGLEPOINT 0x01 +#define DEV_DUALPOINT 0x02 + +#define U1_MOUSE_REPORT_ID 0x01 /* Mouse data ReportID */ +#define U1_ABSOLUTE_REPORT_ID 0x03 /* Absolute data ReportID */ +#define U1_FEATURE_REPORT_ID 0x05 /* Feature ReportID */ +#define U1_SP_ABSOLUTE_REPORT_ID 0x06 /* Feature ReportID */ + +#define U1_FEATURE_REPORT_LEN 0x08 /* Feature Report Length */ +#define U1_FEATURE_REPORT_LEN_ALL 0x0A +#define U1_CMD_REGISTER_READ 0xD1 +#define U1_CMD_REGISTER_WRITE 0xD2 + +#define U1_DEVTYPE_SP_SUPPORT 0x10 /* SP Support */ +#define U1_DISABLE_DEV 0x01 +#define U1_TP_ABS_MODE 0x02 +#define U1_SP_ABS_MODE 0x80 + +#define ADDRESS_U1_DEV_CTRL_1 0x00800040 +#define ADDRESS_U1_DEVICE_TYP 0x00800043 +#define ADDRESS_U1_NUM_SENS_X 0x00800047 +#define ADDRESS_U1_NUM_SENS_Y 0x00800048 +#define ADDRESS_U1_PITCH_SENS_X 0x00800049 +#define ADDRESS_U1_PITCH_SENS_Y 0x0080004A +#define ADDRESS_U1_RESO_DWN_ABS 0x0080004E +#define ADDRESS_U1_PAD_BTN 0x00800052 +#define ADDRESS_U1_SP_BTN 0x0080009F + +#define MAX_TOUCHES 5 + +/** + * struct u1_data + * + * @input: pointer to the kernel input device + * @input2: pointer to the kernel input2 device + * @hdev: pointer to the struct hid_device + * + * @dev_ctrl: device control parameter + * @dev_type: device type + * @sen_line_num_x: number of sensor line of X + * @sen_line_num_y: number of sensor line of Y + * @pitch_x: sensor pitch of X + * @pitch_y: sensor pitch of Y + * @resolution: resolution + * @btn_info: button information + * @x_active_len_mm: active area length of X (mm) + * @y_active_len_mm: active area length of Y (mm) + * @x_max: maximum x coordinate value + * @y_max: maximum y coordinate value + * @btn_cnt: number of buttons + * @sp_btn_cnt: number of stick buttons + */ +struct u1_dev { + struct input_dev *input; + struct input_dev *input2; + struct hid_device *hdev; + + u8 dev_ctrl; + u8 dev_type; + u8 sen_line_num_x; + u8 sen_line_num_y; + u8 pitch_x; + u8 pitch_y; + u8 resolution; + u8 btn_info; + u8 sp_btn_info; + u32 x_active_len_mm; + u32 y_active_len_mm; + u32 x_max; + u32 y_max; + u32 btn_cnt; + u32 sp_btn_cnt; +}; + +struct u1_dev *priv; + +static int u1_read_write_register(struct hid_device *hdev, u32 address, + u8 *read_val, u8 write_val, bool read_flag) +{ + int ret, i; + u8 check_sum; + u8 *input; + u8 *readbuf; + + input = kzalloc(sizeof(u8)*U1_FEATURE_REPORT_LEN, GFP_KERNEL); + if (!input) + return -ENOMEM; + + readbuf = kzalloc(sizeof(u8)*U1_FEATURE_REPORT_LEN, GFP_KERNEL); + if (!readbuf) { + kfree(input); + return -ENOMEM; + } + + input[0] = U1_FEATURE_REPORT_ID; + if (read_flag) { + input[1] = U1_CMD_REGISTER_READ; + input[6] = 0x00; + } else { + input[1] = U1_CMD_REGISTER_WRITE; + input[6] = write_val; + } + + put_unaligned_le32(address, input + 2); + + /* Calculate the checksum */ + check_sum = U1_FEATURE_REPORT_LEN_ALL; + for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++) + check_sum += input[i]; + + input[7] = check_sum; + ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input, + sizeof(input), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); + + if (ret < 0) { + dev_err(&hdev->dev, "failed to read command (%d)\n", ret); + goto exit; + } + + if (read_flag) { + ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, readbuf, + sizeof(readbuf), HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + + if (ret < 0) { + dev_err(&hdev->dev, "failed read register (%d)\n", ret); + goto exit; + } + + *read_val = readbuf[6]; + } + + kfree(input); + kfree(readbuf); + return 0; + +exit: + kfree(input); + kfree(readbuf); + return ret; +} + +static int alps_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) +{ + int x[MAX_TOUCHES], y[MAX_TOUCHES], z[MAX_TOUCHES]; + int i, left, right, middle; + short sp_x, sp_y, sp_z; + struct u1_dev *hdata = hid_get_drvdata(hdev); + + switch (data[0]) { + case U1_MOUSE_REPORT_ID: + break; + case U1_FEATURE_REPORT_ID: + break; + case U1_ABSOLUTE_REPORT_ID: + for (i = 0; i < MAX_TOUCHES; i++) { + x[i] = (data[3+(5*i)] | (data[4+(5*i)] << 8)); + y[i] = (data[5+(5*i)] | (data[6+(5*i)] << 8)); + z[i] = data[7+(5*i)] & 0x7F; + left = data[1] & 0x1; + right = (data[1] & 0x2) >> 1; + middle = (data[1] & 0x4) >> 2; + + input_mt_slot(hdata->input, i); + + if (z[i] != 0) { + input_mt_report_slot_state(hdata->input, + MT_TOOL_FINGER, 1); + } else { + input_mt_report_slot_state(hdata->input, + MT_TOOL_FINGER, 0); + break; + } + + input_event(hdata->input, EV_ABS, + ABS_MT_POSITION_X, x[i]); + input_event(hdata->input, EV_ABS, + ABS_MT_POSITION_Y, y[i]); + input_event(hdata->input, EV_ABS, + ABS_MT_PRESSURE, z[i]); + } + + input_mt_sync_frame(hdata->input); + input_sync(hdata->input); + + input_event(hdata->input, EV_KEY, BTN_LEFT, left); + input_event(hdata->input, EV_KEY, BTN_RIGHT, right); + input_event(hdata->input, EV_KEY, BTN_MIDDLE, middle); + + return 1; + + case U1_SP_ABSOLUTE_REPORT_ID: + sp_x = (data[2] | (data[3] << 8)); + sp_y = (data[4] | (data[5] << 8)); + sp_z = (data[6] | data[7]) & 0x7FFF; + left = data[1] & 0x1; + right = (data[1] & 0x2) >> 1; + middle = (data[1] & 0x4) >> 2; + + sp_x = sp_x / 8; + sp_y = sp_y / 8; + + input_event(priv->input2, EV_REL, REL_X, sp_x); + input_event(priv->input2, EV_REL, REL_Y, sp_y); + + input_event(priv->input2, EV_KEY, BTN_LEFT, left); + input_event(priv->input2, EV_KEY, BTN_RIGHT, right); + input_event(priv->input2, EV_KEY, BTN_MIDDLE, middle); + + input_sync(priv->input2); + + return 1; + } + + return 0; +} + +#ifdef CONFIG_PM +static int alps_post_reset(struct hid_device *hdev) +{ + return u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, U1_TP_ABS_MODE, false); +} + +static int alps_post_resume(struct hid_device *hdev) +{ + return u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, U1_TP_ABS_MODE, false); +} +#endif /* CONFIG_PM */ + +static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) +{ + struct u1_dev *data = hid_get_drvdata(hdev); + struct input_dev *input = hi->input, *input2; + struct u1_dev devInfo; + int ret; + int res_x, res_y, i; + + /* Check device product ID */ + switch (hdev->product) { + case HID_PRODUCT_ID_U1: + case HID_PRODUCT_ID_U1_DUAL: + break; + default: + return 0; + } + + data->input = input; + + hid_dbg(hdev, "Opening low level driver\n"); + ret = hid_hw_open(hdev); + if (ret) + return ret; + + /* Allow incoming hid reports */ + hid_device_io_start(hdev); + + /* Device initialization */ + ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + &devInfo.dev_ctrl, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_DEV_CTRL_1 (%d)\n", ret); + goto exit; + } + + devInfo.dev_ctrl &= ~U1_DISABLE_DEV; + devInfo.dev_ctrl |= U1_TP_ABS_MODE; + ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, devInfo.dev_ctrl, false); + if (ret < 0) { + dev_err(&hdev->dev, "failed to change TP mode (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_X, + &devInfo.sen_line_num_x, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_NUM_SENS_X (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y, + &devInfo.sen_line_num_y, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_X, + &devInfo.pitch_x, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_PITCH_SENS_X (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_Y, + &devInfo.pitch_y, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_PITCH_SENS_Y (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_RESO_DWN_ABS, + &devInfo.resolution, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_RESO_DWN_ABS (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_PAD_BTN, + &devInfo.btn_info, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_PAD_BTN (%d)\n", ret); + goto exit; + } + + /* Check StickPointer device */ + ret = u1_read_write_register(hdev, ADDRESS_U1_DEVICE_TYP, + &devInfo.dev_type, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_DEVICE_TYP (%d)\n", ret); + goto exit; + } + + devInfo.x_active_len_mm = + (devInfo.pitch_x * (devInfo.sen_line_num_x - 1)) / 10; + devInfo.y_active_len_mm = + (devInfo.pitch_y * (devInfo.sen_line_num_y - 1)) / 10; + + devInfo.x_max = + (devInfo.resolution << 2) * (devInfo.sen_line_num_x - 1); + devInfo.y_max = + (devInfo.resolution << 2) * (devInfo.sen_line_num_y - 1); + + __set_bit(EV_ABS, input->evbit); + input_set_abs_params(input, ABS_MT_POSITION_X, 1, devInfo.x_max, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, 1, devInfo.y_max, 0, 0); + + if (devInfo.x_active_len_mm && devInfo.y_active_len_mm) { + res_x = (devInfo.x_max - 1) / devInfo.x_active_len_mm; + res_y = (devInfo.y_max - 1) / devInfo.y_active_len_mm; + + input_abs_set_res(input, ABS_MT_POSITION_X, res_x); + input_abs_set_res(input, ABS_MT_POSITION_Y, res_y); + } + + input_set_abs_params(input, ABS_MT_PRESSURE, 0, 64, 0, 0); + + input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_POINTER); + + __set_bit(EV_KEY, input->evbit); + if ((devInfo.btn_info & 0x0F) == (devInfo.btn_info & 0xF0) >> 4) { + devInfo.btn_cnt = (devInfo.btn_info & 0x0F); + } else { + /* Button pad */ + devInfo.btn_cnt = 1; + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + } + + for (i = 0; i < devInfo.btn_cnt; i++) + __set_bit(BTN_LEFT + i, input->keybit); + + + /* Stick device initialization */ + if (devInfo.dev_type & U1_DEVTYPE_SP_SUPPORT) { + + priv = kzalloc(sizeof(struct u1_dev), GFP_KERNEL); + if (!priv) { + hid_device_io_stop(hdev); + hid_hw_close(hdev); + return -ENOMEM; + } + + input2 = input_allocate_device(); + if (!input2) { + input_free_device(input2); + goto exit; + } + + priv->input2 = input2; + + devInfo.dev_ctrl |= U1_SP_ABS_MODE; + ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, devInfo.dev_ctrl, false); + if (ret < 0) { + dev_err(&hdev->dev, "failed SP mode (%d)\n", ret); + input_free_device(input2); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_SP_BTN, + &devInfo.sp_btn_info, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_SP_BTN (%d)\n", ret); + input_free_device(input2); + goto exit; + } + + input2->phys = input->phys; + input2->name = "DualPoint Stick"; + input2->id.bustype = BUS_I2C; + input2->id.vendor = input->id.vendor; + input2->id.product = input->id.product; + input2->id.version = input->id.version; + input2->dev.parent = input->dev.parent; + + __set_bit(EV_KEY, input2->evbit); + devInfo.sp_btn_cnt = (devInfo.sp_btn_info & 0x0F); + for (i = 0; i < devInfo.sp_btn_cnt; i++) + __set_bit(BTN_LEFT + i, input2->keybit); + + __set_bit(EV_REL, input2->evbit); + __set_bit(REL_X, input2->relbit); + __set_bit(REL_Y, input2->relbit); + __set_bit(INPUT_PROP_POINTER, input2->propbit); + __set_bit(INPUT_PROP_POINTING_STICK, input2->propbit); + + if (input_register_device(priv->input2)) { + input_free_device(input2); + goto exit; + } + } + +exit: + hid_device_io_stop(hdev); + hid_hw_close(hdev); + return ret; +} + +static int alps_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +{ + return -1; +} + +static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct u1_dev *data = NULL; + int ret; + + data = devm_kzalloc(&hdev->dev, sizeof(struct u1_dev), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->hdev = hdev; + hid_set_drvdata(hdev, data); + + hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed\n"); + return ret; + } + + return 0; +} + +static void alps_remove(struct hid_device *hdev) +{ + hid_hw_stop(hdev); + kfree(priv); +} + +static const struct hid_device_id alps_id[] = { + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, + USB_VENDOR_ID_ALPS_JP, HID_ANY_ID) }, + { } +}; +MODULE_DEVICE_TABLE(hid, alps_id); + +static struct hid_driver alps_driver = { + .name = "hid-alps", + .id_table = alps_id, + .probe = alps_probe, + .remove = alps_remove, + .raw_event = alps_raw_event, + .input_mapping = alps_input_mapping, + .input_configured = alps_input_configured, +#ifdef CONFIG_PM + .resume = alps_post_resume, + .reset_resume = alps_post_reset, +#endif +}; + +module_hid_driver(alps_driver); + +MODULE_AUTHOR("Masaki Ota "); +MODULE_DESCRIPTION("ALPS HID driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3eec09a134cb..a5a429cbf163 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -70,6 +70,8 @@ #define USB_VENDOR_ID_ALPS 0x0433 #define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 +#define USB_VENDOR_ID_ALPS_JP 0x044E + #define USB_VENDOR_ID_ANTON 0x1130 #define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101 -- cgit v1.3-14-g43fede From 0aefa05420c0e81eec2496b28a1b5d6e7783cb23 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Fri, 27 May 2016 12:43:45 -0600 Subject: libnvdimm, btt: update the usage section in Documentation Section 5 about BTT's in kernel usage was quite obsolete, replace it with a simple 'Usage' section that describes how to set up a BTT namespace using the 'ndctl' utility. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- Documentation/nvdimm/btt.txt | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'Documentation') diff --git a/Documentation/nvdimm/btt.txt b/Documentation/nvdimm/btt.txt index b91443f577dc..e293fb664924 100644 --- a/Documentation/nvdimm/btt.txt +++ b/Documentation/nvdimm/btt.txt @@ -256,28 +256,18 @@ If any of these error conditions are encountered, the arena is put into a read only state using a flag in the info block. -5. In-kernel usage -================== +5. Usage +======== -Any block driver that supports byte granularity IO to the storage may register -with the BTT. It will have to provide the rw_bytes interface in its -block_device_operations struct: +The BTT can be set up on any disk (namespace) exposed by the libnvdimm subsystem +(pmem, or blk mode). The easiest way to set up such a namespace is using the +'ndctl' utility [1]: - int (*rw_bytes)(struct gendisk *, void *, size_t, off_t, int rw); +For example, the ndctl command line to setup a btt with a 4k sector size is: -It may register with the BTT after it adds its own gendisk, using btt_init: + ndctl create-namespace -f -e namespace0.0 -m sector -l 4k - struct btt *btt_init(struct gendisk *disk, unsigned long long rawsize, - u32 lbasize, u8 uuid[], int maxlane); +See ndctl create-namespace --help for more options. -note that maxlane is the maximum amount of concurrency the driver wishes to -allow the BTT to use. - -The BTT 'disk' appears as a stacked block device that grabs the underlying block -device in the O_EXCL mode. - -When the driver wishes to remove the backing disk, it should similarly call -btt_fini using the same struct btt* handle that was provided to it by btt_init. - - void btt_fini(struct btt *btt); +[1]: https://github.com/pmem/ndctl -- cgit v1.3-14-g43fede From 6774b68b2435a129850542f9b7a3b9ce375291c6 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Fri, 17 Jun 2016 13:25:40 +0300 Subject: Documentation: DT: cpsw: remove rx_descs property There is no reason to hold s/w dependent parameter in device tree. Even more, there is no reason in this parameter because davinici_cpdma driver splits pool of descriptors equally between tx and rx channels anyway. Acked-by: Rob Herring Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/cpsw.txt | 1 - arch/arm/boot/dts/am33xx.dtsi | 1 - arch/arm/boot/dts/am4372.dtsi | 1 - arch/arm/boot/dts/dm814x.dtsi | 1 - arch/arm/boot/dts/dra7.dtsi | 1 - 5 files changed, 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt index 0ae06491b430..5ad439f30135 100644 --- a/Documentation/devicetree/bindings/net/cpsw.txt +++ b/Documentation/devicetree/bindings/net/cpsw.txt @@ -15,7 +15,6 @@ Required properties: - cpdma_channels : Specifies number of channels in CPDMA - ale_entries : Specifies No of entries ALE can hold - bd_ram_size : Specifies internal descriptor RAM size -- rx_descs : Specifies number of Rx descriptors - mac_control : Specifies Default MAC control register content for the specific platform - slaves : Specifies number for slaves diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 52be48bbd2dd..702126ff4a56 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -766,7 +766,6 @@ ale_entries = <1024>; bd_ram_size = <0x2000>; no_bd_ram = <0>; - rx_descs = <64>; mac_control = <0x20>; slaves = <2>; active_slave = <0>; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 12fcde4d4d2e..a10fa7f95442 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -626,7 +626,6 @@ ale_entries = <1024>; bd_ram_size = <0x2000>; no_bd_ram = <0>; - rx_descs = <64>; mac_control = <0x20>; slaves = <2>; active_slave = <0>; diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi index d4537dc61497..f23cae0c2179 100644 --- a/arch/arm/boot/dts/dm814x.dtsi +++ b/arch/arm/boot/dts/dm814x.dtsi @@ -509,7 +509,6 @@ ale_entries = <1024>; bd_ram_size = <0x2000>; no_bd_ram = <0>; - rx_descs = <64>; mac_control = <0x20>; slaves = <2>; active_slave = <0>; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index e0074014385a..b7ddc645dd52 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -1626,7 +1626,6 @@ ale_entries = <1024>; bd_ram_size = <0x2000>; no_bd_ram = <0>; - rx_descs = <64>; mac_control = <0x20>; slaves = <2>; active_slave = <0>; -- cgit v1.3-14-g43fede From fa4191a609f219262a18dd8b02ab7dc30896b707 Mon Sep 17 00:00:00 2001 From: Phil Reid Date: Tue, 14 Jun 2016 15:36:17 +0800 Subject: leds: pca9532: Add device tree support This patch adds basic device tree support for the pca9532 LEDs. Signed-off-by: Phil Reid Signed-off-by: Jacek Anaszewski --- .../devicetree/bindings/leds/leds-pca9532.txt | 39 +++++++++++ drivers/leds/leds-pca9532.c | 75 ++++++++++++++++++++-- include/dt-bindings/leds/leds-pca9532.h | 18 ++++++ include/linux/leds-pca9532.h | 9 ++- 4 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/leds/leds-pca9532.txt create mode 100644 include/dt-bindings/leds/leds-pca9532.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/leds/leds-pca9532.txt b/Documentation/devicetree/bindings/leds/leds-pca9532.txt new file mode 100644 index 000000000000..198f3ba0e01f --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-pca9532.txt @@ -0,0 +1,39 @@ +*NXP - pca9532 PWM LED Driver + +The PCA9532 family is SMBus I/O expander optimized for dimming LEDs. +The PWM support 256 steps. + +Required properties: + - compatible: + "nxp,pca9530" + "nxp,pca9531" + "nxp,pca9532" + "nxp,pca9533" + - reg - I2C slave address + +Each led is represented as a sub-node of the nxp,pca9530. + +Optional sub-node properties: + - label: see Documentation/devicetree/bindings/leds/common.txt + - type: Output configuration, see dt-bindings/leds/leds-pca9532.h (default NONE) + - linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt + +Example: + #include + + leds: pca9530@60 { + compatible = "nxp,pca9530"; + reg = <0x60>; + + red-power { + label = "pca:red:power"; + type = ; + }; + green-power { + label = "pca:green:power"; + type = ; + }; + }; + +For more product information please see the link below: +http://nxp.com/documents/data_sheet/PCA9532.pdf diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index e3d3b1aaa9e0..09a7cffbc46f 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include /* m = num_leds*/ #define PCA9532_REG_INPUT(i) ((i) >> 3) @@ -86,9 +88,22 @@ static const struct pca9532_chip_info pca9532_chip_info_tbl[] = { }, }; +#ifdef CONFIG_OF +static const struct of_device_id of_pca9532_leds_match[] = { + { .compatible = "nxp,pca9530", .data = (void *)pca9530 }, + { .compatible = "nxp,pca9531", .data = (void *)pca9531 }, + { .compatible = "nxp,pca9532", .data = (void *)pca9532 }, + { .compatible = "nxp,pca9533", .data = (void *)pca9533 }, + {}, +}; + +MODULE_DEVICE_TABLE(of, of_pca9532_leds_match); +#endif + static struct i2c_driver pca9532_driver = { .driver = { .name = "leds-pca953x", + .of_match_table = of_match_ptr(of_pca9532_leds_match), }, .probe = pca9532_probe, .remove = pca9532_remove, @@ -354,6 +369,7 @@ static int pca9532_configure(struct i2c_client *client, led->state = pled->state; led->name = pled->name; led->ldev.name = led->name; + led->ldev.default_trigger = led->default_trigger; led->ldev.brightness = LED_OFF; led->ldev.brightness_set_blocking = pca9532_set_brightness; @@ -432,15 +448,66 @@ exit: return err; } +static struct pca9532_platform_data * +pca9532_of_populate_pdata(struct device *dev, struct device_node *np) +{ + struct pca9532_platform_data *pdata; + struct device_node *child; + const struct of_device_id *match; + int devid, maxleds; + int i = 0; + + match = of_match_device(of_pca9532_leds_match, dev); + if (!match) + return ERR_PTR(-ENODEV); + + devid = (int)(uintptr_t)match->data; + maxleds = pca9532_chip_info_tbl[devid].num_leds; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + for_each_child_of_node(np, child) { + if (of_property_read_string(child, "label", + &pdata->leds[i].name)) + pdata->leds[i].name = child->name; + of_property_read_u32(child, "type", &pdata->leds[i].type); + of_property_read_string(child, "linux,default-trigger", + &pdata->leds[i].default_trigger); + if (++i >= maxleds) { + of_node_put(child); + break; + } + } + + return pdata; +} + static int pca9532_probe(struct i2c_client *client, const struct i2c_device_id *id) { + int devid; struct pca9532_data *data = i2c_get_clientdata(client); struct pca9532_platform_data *pca9532_pdata = dev_get_platdata(&client->dev); - - if (!pca9532_pdata) - return -EIO; + struct device_node *np = client->dev.of_node; + + if (!pca9532_pdata) { + if (np) { + pca9532_pdata = + pca9532_of_populate_pdata(&client->dev, np); + if (IS_ERR(pca9532_pdata)) + return PTR_ERR(pca9532_pdata); + } else { + dev_err(&client->dev, "no platform data\n"); + return -EINVAL; + } + devid = (int)(uintptr_t)of_match_device( + of_pca9532_leds_match, &client->dev)->data; + } else { + devid = id->driver_data; + } if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -450,7 +517,7 @@ static int pca9532_probe(struct i2c_client *client, if (!data) return -ENOMEM; - data->chip_info = &pca9532_chip_info_tbl[id->driver_data]; + data->chip_info = &pca9532_chip_info_tbl[devid]; dev_info(&client->dev, "setting platform data\n"); i2c_set_clientdata(client, data); diff --git a/include/dt-bindings/leds/leds-pca9532.h b/include/dt-bindings/leds/leds-pca9532.h new file mode 100644 index 000000000000..4d917aab7e1e --- /dev/null +++ b/include/dt-bindings/leds/leds-pca9532.h @@ -0,0 +1,18 @@ +/* + * This header provides constants for pca9532 LED bindings. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef _DT_BINDINGS_LEDS_PCA9532_H +#define _DT_BINDINGS_LEDS_PCA9532_H + +#define PCA9532_TYPE_NONE 0 +#define PCA9532_TYPE_LED 1 +#define PCA9532_TYPE_N2100_BEEP 2 +#define PCA9532_TYPE_GPIO 3 +#define PCA9532_LED_TIMER2 4 + +#endif /* _DT_BINDINGS_LEDS_PCA9532_H */ diff --git a/include/linux/leds-pca9532.h b/include/linux/leds-pca9532.h index b8d6fffed4d8..d215b4561180 100644 --- a/include/linux/leds-pca9532.h +++ b/include/linux/leds-pca9532.h @@ -16,6 +16,7 @@ #include #include +#include enum pca9532_state { PCA9532_OFF = 0x0, @@ -24,16 +25,14 @@ enum pca9532_state { PCA9532_PWM1 = 0x3 }; -enum pca9532_type { PCA9532_TYPE_NONE, PCA9532_TYPE_LED, - PCA9532_TYPE_N2100_BEEP, PCA9532_TYPE_GPIO }; - struct pca9532_led { u8 id; struct i2c_client *client; - char *name; + const char *name; + const char *default_trigger; struct led_classdev ldev; struct work_struct work; - enum pca9532_type type; + u32 type; enum pca9532_state state; }; -- cgit v1.3-14-g43fede From 35abb67de744b5dbaec54381f2f9e0246089331d Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Wed, 8 Jun 2016 18:38:02 -0700 Subject: tracing: expose current->comm to [ku]probe events ftrace is very quick to give up on saving the task command line (see `trace_save_cmdline()`). The workaround for events which really care about the command line is to explicitly assign it as part of the entry. However, this doesn't work for kprobe events, as there's no straightforward way to get access to current->comm. Add a kprobe/uprobe event variable $comm which provides exactly that. Link: http://lkml.kernel.org/r/f59b472033b943a370f5f48d0af37698f409108f.1465435894.git.osandov@fb.com Acked-by: Masami Hiramatsu Signed-off-by: Omar Sandoval Signed-off-by: Steven Rostedt --- Documentation/trace/kprobetrace.txt | 3 +++ Documentation/trace/uprobetracer.txt | 3 +++ kernel/trace/trace_kprobe.c | 1 + kernel/trace/trace_probe.c | 33 +++++++++++++++++++++++++++++++++ kernel/trace/trace_probe.h | 10 ++++++++++ 5 files changed, 50 insertions(+) (limited to 'Documentation') diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index d68ea5fc812b..ea52ec1f8484 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt @@ -40,6 +40,7 @@ Synopsis of kprobe_events $stackN : Fetch Nth entry of stack (N >= 0) $stack : Fetch stack address. $retval : Fetch return value.(*) + $comm : Fetch current task comm. +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) NAME=FETCHARG : Set NAME as the argument name of FETCHARG. FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types @@ -62,6 +63,8 @@ offset, and container-size (usually 32). The syntax is; b@/ +For $comm, the default type is "string"; any other type is invalid. + Per-Probe Event Filtering ------------------------- diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt index f1cf9a34ad9d..72d1cd4f7bf3 100644 --- a/Documentation/trace/uprobetracer.txt +++ b/Documentation/trace/uprobetracer.txt @@ -36,6 +36,7 @@ Synopsis of uprobe_tracer $stackN : Fetch Nth entry of stack (N >= 0) $stack : Fetch stack address. $retval : Fetch return value.(*) + $comm : Fetch current task comm. +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) NAME=FETCHARG : Set NAME as the argument name of FETCHARG. FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types @@ -57,6 +58,8 @@ offset, and container-size (usually 32). The syntax is; b@/ +For $comm, the default type is "string"; any other type is invalid. + Event Profiling --------------- diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5546eec0505f..9aedb0b06683 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -587,6 +587,7 @@ static int create_trace_kprobe(int argc, char **argv) * $retval : fetch return value * $stack : fetch stack address * $stackN : fetch Nth of stack (N:0-) + * $comm : fetch current task comm * @ADDR : fetch memory at ADDR (ADDR should be in kernel) * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) * %REG : fetch register REG diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 1d372fa6fefb..74e80a582c28 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -218,6 +218,28 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data) kfree(data); } +void FETCH_FUNC_NAME(comm, string)(struct pt_regs *regs, + void *data, void *dest) +{ + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + long ret; + + if (!maxlen) + return; + + ret = strlcpy(dst, current->comm, maxlen); + *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest)); +} +NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string)); + +void FETCH_FUNC_NAME(comm, string_size)(struct pt_regs *regs, + void *data, void *dest) +{ + *(u32 *)dest = strlen(current->comm) + 1; +} +NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string_size)); + static const struct fetch_type *find_fetch_type(const char *type, const struct fetch_type *ftbl) { @@ -348,6 +370,11 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, } } else ret = -EINVAL; + } else if (strcmp(arg, "comm") == 0) { + if (strcmp(t->name, "string") != 0 && + strcmp(t->name, "string_size") != 0) + return -EINVAL; + f->fn = t->fetch[FETCH_MTD_comm]; } else ret = -EINVAL; @@ -522,6 +549,12 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, arg[t - parg->comm] = '\0'; t++; } + /* + * The default type of $comm should be "string", and it can't be + * dereferenced. + */ + if (!t && strcmp(arg, "$comm") == 0) + t = "string"; parg->type = find_fetch_type(t, ftbl); if (!parg->type) { pr_info("Unsupported type: %s\n", t); diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index f6398db09114..45400ca5ded1 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -102,6 +102,7 @@ enum { FETCH_MTD_reg = 0, FETCH_MTD_stack, FETCH_MTD_retval, + FETCH_MTD_comm, FETCH_MTD_memory, FETCH_MTD_symbol, FETCH_MTD_deref, @@ -183,6 +184,14 @@ DECLARE_BASIC_FETCH_FUNCS(bitfield); #define fetch_bitfield_string NULL #define fetch_bitfield_string_size NULL +/* comm only makes sense as a string */ +#define fetch_comm_u8 NULL +#define fetch_comm_u16 NULL +#define fetch_comm_u32 NULL +#define fetch_comm_u64 NULL +DECLARE_FETCH_FUNC(comm, string); +DECLARE_FETCH_FUNC(comm, string_size); + /* * Define macro for basic types - we don't need to define s* types, because * we have to care only about bitwidth at recording time. @@ -213,6 +222,7 @@ DEFINE_FETCH_##method(u64) ASSIGN_FETCH_FUNC(reg, ftype), \ ASSIGN_FETCH_FUNC(stack, ftype), \ ASSIGN_FETCH_FUNC(retval, ftype), \ +ASSIGN_FETCH_FUNC(comm, ftype), \ ASSIGN_FETCH_FUNC(memory, ftype), \ ASSIGN_FETCH_FUNC(symbol, ftype), \ ASSIGN_FETCH_FUNC(deref, ftype), \ -- cgit v1.3-14-g43fede From b7eaa9ffa6a44c4efabdd9d430e882d67c92c5e8 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 6 Jan 2016 12:05:17 +0100 Subject: drm/bridge: Add sii902x DT bindings doc Add Sii9022 DT bindings description. Signed-off-by: Boris Brezillon Acked-by: Rob Herring --- Changes since v6: - make 'reset-gpios' optional Changes since v1: - rename doc file - s/sil902/sii902/ --- .../devicetree/bindings/display/bridge/sii902x.txt | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/sii902x.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/bridge/sii902x.txt b/Documentation/devicetree/bindings/display/bridge/sii902x.txt new file mode 100644 index 000000000000..56a3e68ccb80 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/sii902x.txt @@ -0,0 +1,35 @@ +sii902x HDMI bridge bindings + +Required properties: + - compatible: "sil,sii9022" + - reg: i2c address of the bridge + +Optional properties: + - interrupts-extended or interrupt-parent + interrupts: describe + the interrupt line used to inform the host about hotplug events. + - reset-gpios: OF device-tree gpio specification for RST_N pin. + +Optional subnodes: + - video input: this subnode can contain a video input port node + to connect the bridge to a display controller output (See this + documentation [1]). + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + hdmi-bridge@39 { + compatible = "sil,sii9022"; + reg = <0x39>; + reset-gpios = <&pioA 1 0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + bridge_in: endpoint { + remote-endpoint = <&dc_out>; + }; + }; + }; + }; -- cgit v1.3-14-g43fede From aa5e94a2e13377e374795de5400e346c978f46be Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Jun 2016 07:42:07 -0700 Subject: Revert "usb: ohci-at91: Forcibly suspend ports while USB suspend" This reverts commit 7150bc9b4d43471fa37b26f5839892d4cf1fe09b. It is not correct, based on review from others. Reported-by: Wenyou Yang Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/atmel-usb.txt | 6 +- drivers/usb/host/ohci-at91.c | 80 +--------------------- include/soc/at91/at91_sfr.h | 29 -------- 3 files changed, 3 insertions(+), 112 deletions(-) delete mode 100644 include/soc/at91/at91_sfr.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt index 888deaa8a4ca..5883b73ea1b5 100644 --- a/Documentation/devicetree/bindings/usb/atmel-usb.txt +++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt @@ -3,10 +3,8 @@ Atmel SOC USB controllers OHCI Required properties: - - compatible: Should be one of the following - "atmel,at91rm9200-ohci" for USB controllers used in host mode. - "atmel,sama5d2-ohci" for USB controllers used in host mode - on SAMA5D2 which can force to suspend. + - compatible: Should be "atmel,at91rm9200-ohci" for USB controllers + used in host mode. - reg: Address and length of the register set for the device - interrupts: Should contain ehci interrupt - clocks: Should reference the peripheral, host and system clocks diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 54e8feb8a964..d177372bb357 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -21,11 +21,8 @@ #include #include #include -#include -#include #include #include -#include #include "ohci.h" @@ -48,18 +45,12 @@ struct at91_usbh_data { u8 overcurrent_changed[AT91_MAX_USBH_PORTS]; }; -struct ohci_at91_caps { - bool suspend_ctrl; -}; - struct ohci_at91_priv { struct clk *iclk; struct clk *fclk; struct clk *hclk; bool clocked; bool wakeup; /* Saved wake-up state for resume */ - const struct ohci_at91_caps *caps; - struct regmap *sfr_regmap; }; /* interface and function clocks; sometimes also an AHB clock */ @@ -141,17 +132,6 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -struct regmap *at91_dt_syscon_sfr(void) -{ - struct regmap *regmap; - - regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); - if (IS_ERR(regmap)) - regmap = NULL; - - return regmap; -} - static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ @@ -217,17 +197,6 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, goto err; } - ohci_at91->caps = (const struct ohci_at91_caps *) - of_device_get_match_data(&pdev->dev); - if (!ohci_at91->caps) - return -ENODEV; - - if (ohci_at91->caps->suspend_ctrl) { - ohci_at91->sfr_regmap = at91_dt_syscon_sfr(); - if (!ohci_at91->sfr_regmap) - dev_warn(dev, "failed to find sfr node\n"); - } - board = hcd->self.controller->platform_data; ohci = hcd_to_ohci(hcd); ohci->num_ports = board->ports; @@ -471,17 +440,8 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) return IRQ_HANDLED; } -static const struct ohci_at91_caps at91rm9200_caps = { - .suspend_ctrl = false, -}; - -static const struct ohci_at91_caps sama5d2_caps = { - .suspend_ctrl = true, -}; - static const struct of_device_id at91_ohci_dt_ids[] = { - { .compatible = "atmel,at91rm9200-ohci", .data = &at91rm9200_caps }, - { .compatible = "atmel,sama5d2-ohci", .data = &sama5d2_caps }, + { .compatible = "atmel,at91rm9200-ohci" }, { /* sentinel */ } }; @@ -621,38 +581,6 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) return 0; } -static int ohci_at91_port_ctrl(struct regmap *regmap, bool enable) -{ - u32 regval; - int ret; - - if (!regmap) - return -EINVAL; - - ret = regmap_read(regmap, SFR_OHCIICR, ®val); - if (ret) - return ret; - - if (enable) - regval &= ~SFR_OHCIICR_USB_SUSPEND; - else - regval |= SFR_OHCIICR_USB_SUSPEND; - - regmap_write(regmap, SFR_OHCIICR, regval); - - return 0; -} - -static int ohci_at91_port_suspend(struct regmap *regmap) -{ - return ohci_at91_port_ctrl(regmap, false); -} - -static int ohci_at91_port_resume(struct regmap *regmap) -{ - return ohci_at91_port_ctrl(regmap, true); -} - static int __maybe_unused ohci_hcd_at91_drv_suspend(struct device *dev) { @@ -690,9 +618,6 @@ ohci_hcd_at91_drv_suspend(struct device *dev) ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); ohci->rh_state = OHCI_RH_HALTED; - if (ohci_at91->caps->suspend_ctrl) - ohci_at91_port_suspend(ohci_at91->sfr_regmap); - /* flush the writes */ (void) ohci_readl (ohci, &ohci->regs->control); at91_stop_clock(ohci_at91); @@ -712,9 +637,6 @@ ohci_hcd_at91_drv_resume(struct device *dev) at91_start_clock(ohci_at91); - if (ohci_at91->caps->suspend_ctrl) - ohci_at91_port_resume(ohci_at91->sfr_regmap); - ohci_resume(hcd, false); return 0; } diff --git a/include/soc/at91/at91_sfr.h b/include/soc/at91/at91_sfr.h deleted file mode 100644 index 04a3a1eee22e..000000000000 --- a/include/soc/at91/at91_sfr.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Header file for the Atmel DDR/SDR SDRAM Controller - * - * Copyright (C) 2016 Atmel Corporation - * - * Author: Wenyou Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#ifndef __AT91_SFR_H__ -#define __AT91_SFR_H__ - -#define SFR_DDRCFG 0x04 /* DDR Configuration Register */ -/* 0x08 ~ 0x0c: Reserved */ -#define SFR_OHCIICR 0x10 /* OHCI Interrupt Configuration Register */ -#define SFR_OHCIISR 0x14 /* OHCI Interrupt Status Register */ - -#define SFR_OHCIICR_SUSPEND_A BIT(8) -#define SFR_OHCIICR_SUSPEND_B BIT(9) -#define SFR_OHCIICR_SUSPEND_C BIT(10) - -#define SFR_OHCIICR_USB_SUSPEND (SFR_OHCIICR_SUSPEND_A | \ - SFR_OHCIICR_SUSPEND_B | \ - SFR_OHCIICR_SUSPEND_C) - -#endif -- cgit v1.3-14-g43fede From cafc4cd0c8b81caa32312d8f1d801a21beaccba1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 14 Jun 2016 08:00:20 -0500 Subject: arm64: dts: apm: Use lowercase consistently for hex constants The convention in these files is to use lowercase for "0x" prefixes and for the hex constants themselves, but a few changes didn't follow that convention, which makes the file annoying to read. Use lowercase consistently for the hex constants. No functional change intended. Signed-off-by: Bjorn Helgaas Acked-by: Rob Herring Signed-off-by: Duc Dang --- .../devicetree/bindings/net/apm-xgene-enet.txt | 4 +-- arch/arm64/boot/dts/apm/apm-shadowcat.dtsi | 40 +++++++++++----------- arch/arm64/boot/dts/apm/apm-storm.dtsi | 36 +++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt index 05f705e32a4a..e41b2d59ca7f 100644 --- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt +++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt @@ -59,8 +59,8 @@ Example: compatible = "apm,xgene-enet"; status = "disabled"; reg = <0x0 0x17020000 0x0 0xd100>, - <0x0 0X17030000 0x0 0X400>, - <0x0 0X10000000 0x0 0X200>; + <0x0 0x17030000 0x0 0x400>, + <0x0 0x10000000 0x0 0x200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; interrupts = <0x0 0x3c 0x4>; port-id = <0>; diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi index c569f761d090..977368745f39 100644 --- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi @@ -106,9 +106,9 @@ interrupts = <1 9 0xf04>; /* GIC Maintenence IRQ */ ranges = <0 0 0 0x79000000 0x0 0x800000>; /* MSI Range */ reg = <0x0 0x78090000 0x0 0x10000>, /* GIC Dist */ - <0x0 0x780A0000 0x0 0x20000>, /* GIC CPU */ - <0x0 0x780C0000 0x0 0x10000>, /* GIC VCPU Control */ - <0x0 0x780E0000 0x0 0x20000>; /* GIC VCPU */ + <0x0 0x780a0000 0x0 0x20000>, /* GIC CPU */ + <0x0 0x780c0000 0x0 0x10000>, /* GIC VCPU Control */ + <0x0 0x780e0000 0x0 0x20000>; /* GIC VCPU */ v2m0: v2m@0x00000 { compatible = "arm,gic-v2m-frame"; msi-controller; @@ -159,35 +159,35 @@ msi-controller; reg = <0x0 0x90000 0x0 0x1000>; }; - v2m10: v2m@0xA0000 { + v2m10: v2m@0xa0000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0x0 0xA0000 0x0 0x1000>; + reg = <0x0 0xa0000 0x0 0x1000>; }; - v2m11: v2m@0xB0000 { + v2m11: v2m@0xb0000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0x0 0xB0000 0x0 0x1000>; + reg = <0x0 0xb0000 0x0 0x1000>; }; - v2m12: v2m@0xC0000 { + v2m12: v2m@0xc0000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0x0 0xC0000 0x0 0x1000>; + reg = <0x0 0xc0000 0x0 0x1000>; }; - v2m13: v2m@0xD0000 { + v2m13: v2m@0xd0000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0x0 0xD0000 0x0 0x1000>; + reg = <0x0 0xd0000 0x0 0x1000>; }; - v2m14: v2m@0xE0000 { + v2m14: v2m@0xe0000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0x0 0xE0000 0x0 0x1000>; + reg = <0x0 0xe0000 0x0 0x1000>; }; - v2m15: v2m@0xF0000 { + v2m15: v2m@0xf0000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0x0 0xF0000 0x0 0x1000>; + reg = <0x0 0xf0000 0x0 0x1000>; }; }; @@ -629,8 +629,8 @@ compatible = "apm,xgene2-sgenet"; status = "disabled"; reg = <0x0 0x1f610000 0x0 0x10000>, - <0x0 0x1f600000 0x0 0Xd100>, - <0x0 0x20000000 0x0 0X20000>; + <0x0 0x1f600000 0x0 0xd100>, + <0x0 0x20000000 0x0 0x20000>; interrupts = <0 96 4>, <0 97 4>; dma-coherent; @@ -643,8 +643,8 @@ compatible = "apm,xgene2-xgenet"; status = "disabled"; reg = <0x0 0x1f620000 0x0 0x10000>, - <0x0 0x1f600000 0x0 0Xd100>, - <0x0 0x20000000 0x0 0X220000>; + <0x0 0x1f600000 0x0 0xd100>, + <0x0 0x20000000 0x0 0x220000>; interrupts = <0 108 4>, <0 109 4>, <0 110 4>, @@ -684,7 +684,7 @@ #size-cells = <0>; compatible = "snps,designware-i2c"; reg = <0x0 0x10640000 0x0 0x1000>; - interrupts = <0 0x3A 0x4>; + interrupts = <0 0x3a 0x4>; clocks = <&i2c4clk 0>; bus_num = <4>; }; diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index 5147d7698924..e0e8d2a3eaf2 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -204,7 +204,7 @@ #clock-cells = <1>; clocks = <&socplldiv2 0>; clock-names = "qmlclk"; - reg = <0x0 0x1703C000 0x0 0x1000>; + reg = <0x0 0x1703c000 0x0 0x1000>; reg-names = "csr-reg"; clock-output-names = "qmlclk"; }; @@ -226,7 +226,7 @@ compatible = "apm,xgene-device-clock"; #clock-cells = <1>; clocks = <ðclk 0>; - reg = <0x0 0x1702C000 0x0 0x1000>; + reg = <0x0 0x1702c000 0x0 0x1000>; reg-names = "csr-reg"; clock-output-names = "menetclk"; }; @@ -925,8 +925,8 @@ compatible = "apm,xgene-enet"; status = "disabled"; reg = <0x0 0x17020000 0x0 0xd100>, - <0x0 0X17030000 0x0 0Xc300>, - <0x0 0X10000000 0x0 0X200>; + <0x0 0x17030000 0x0 0xc300>, + <0x0 0x10000000 0x0 0x200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; interrupts = <0x0 0x3c 0x4>; dma-coherent; @@ -951,11 +951,11 @@ compatible = "apm,xgene1-sgenet"; status = "disabled"; reg = <0x0 0x1f210000 0x0 0xd100>, - <0x0 0x1f200000 0x0 0Xc300>, - <0x0 0x1B000000 0x0 0X200>; + <0x0 0x1f200000 0x0 0xc300>, + <0x0 0x1b000000 0x0 0x200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; - interrupts = <0x0 0xA0 0x4>, - <0x0 0xA1 0x4>; + interrupts = <0x0 0xa0 0x4>, + <0x0 0xa1 0x4>; dma-coherent; clocks = <&sge0clk 0>; local-mac-address = [00 00 00 00 00 00]; @@ -966,11 +966,11 @@ compatible = "apm,xgene1-sgenet"; status = "disabled"; reg = <0x0 0x1f210030 0x0 0xd100>, - <0x0 0x1f200000 0x0 0Xc300>, - <0x0 0x1B000000 0x0 0X8000>; + <0x0 0x1f200000 0x0 0xc300>, + <0x0 0x1b000000 0x0 0x8000>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; - interrupts = <0x0 0xAC 0x4>, - <0x0 0xAD 0x4>; + interrupts = <0x0 0xac 0x4>, + <0x0 0xad 0x4>; port-id = <1>; dma-coherent; clocks = <&sge1clk 0>; @@ -982,8 +982,8 @@ compatible = "apm,xgene1-xgenet"; status = "disabled"; reg = <0x0 0x1f610000 0x0 0xd100>, - <0x0 0x1f600000 0x0 0Xc300>, - <0x0 0x18000000 0x0 0X200>; + <0x0 0x1f600000 0x0 0xc300>, + <0x0 0x18000000 0x0 0x200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; interrupts = <0x0 0x60 0x4>, <0x0 0x61 0x4>, @@ -1005,11 +1005,11 @@ compatible = "apm,xgene1-xgenet"; status = "disabled"; reg = <0x0 0x1f620000 0x0 0xd100>, - <0x0 0x1f600000 0x0 0Xc300>, - <0x0 0x18000000 0x0 0X8000>; + <0x0 0x1f600000 0x0 0xc300>, + <0x0 0x18000000 0x0 0x8000>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; - interrupts = <0x0 0x6C 0x4>, - <0x0 0x6D 0x4>; + interrupts = <0x0 0x6c 0x4>, + <0x0 0x6d 0x4>; port-id = <1>; dma-coherent; clocks = <&xge1clk 0>; -- cgit v1.3-14-g43fede From ebfad91c5da3b32d83aaad280d6918867aea501c Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Thu, 16 Jun 2016 16:13:18 +0800 Subject: dt-bindings: ci-hdrc-usb2: s/gadget-itc-setting/itc-setting in example What the code expect is "itc-setting" rather than "gadget-itc-setting", and this is also correctly described in the optional properties. Signed-off-by: Jisheng Zhang Signed-off-by: Peter Chen Acked-by: Rob Herring --- Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 1084e2bcbe1c..341dc67f3472 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt @@ -93,7 +93,7 @@ Example: phys = <&usb_phy0>; phy-names = "usb-phy"; vbus-supply = <®_usb0_vbus>; - gadget-itc-setting = <0x4>; /* 4 micro-frames */ + itc-setting = <0x4>; /* 4 micro-frames */ /* Incremental burst of unspecified length */ ahb-burst-config = <0x0>; tx-burst-size-dword = <0x10>; /* 64 bytes */ -- cgit v1.3-14-g43fede From 846d9ce535309798ae6d8c8781b0207f3cb41e6e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 1 Jun 2016 16:13:12 +0100 Subject: extcon: arizona: Update binding docs to mention new defines for GPSW Update the binding documentation to mention the defines added for the possible values of wlf,gpsw. Signed-off-by: Charles Keepax Signed-off-by: Chanwoo Choi --- Documentation/devicetree/bindings/extcon/extcon-arizona.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt index e27341f8a4c7..7f3d94ae81ff 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -46,7 +46,8 @@ Optional properties: The second cell represents the MICBIAS to be used. The third cell represents the value of the micd-pol-gpio pin. - - wlf,gpsw : Settings for the general purpose switch + - wlf,gpsw : Settings for the general purpose switch, set as one of the + ARIZONA_GPSW_XXX defines. Example: -- cgit v1.3-14-g43fede From 13445de6e71ad219f8fce8736c45f57bb3b85571 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 3 Jun 2016 23:58:03 +0300 Subject: clk: renesas: rcar-gen2: Document R8A7792 support Renesas R8A7792 SoC is a member of the R-Car gen2 family and so has CPG... Signed-off-by: Sergei Shtylyov Acked-by: Simon Horman Acked-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt index 2a9a8edc8f35..f8c05bb4116e 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt @@ -10,6 +10,7 @@ Required Properties: - compatible: Must be one of - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG + - "renesas,r8a7792-cpg-clocks" for the r8a7792 CPG - "renesas,r8a7793-cpg-clocks" for the r8a7793 CPG - "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG and "renesas,rcar-gen2-cpg-clocks" as a fallback. -- cgit v1.3-14-g43fede From ef71b1eaa0e09a082027f15f9e040a6f636ce874 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 3 Jun 2016 23:59:07 +0300 Subject: clk: renesas: mstp: Document R8A7792 support Renesas R8A7792 SoC also has the CPG MSTP clocks... Signed-off-by: Sergei Shtylyov Acked-by: Simon Horman Acked-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt index 16ed18155160..da578ebdda28 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt @@ -17,6 +17,7 @@ Required Properties: - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2-W) MSTP gate clocks + - "renesas,r8a7792-mstp-clocks" for R8A7792 (R-Car V2H) MSTP gate clocks - "renesas,r8a7793-mstp-clocks" for R8A7793 (R-Car M2-N) MSTP gate clocks - "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks - "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks -- cgit v1.3-14-g43fede From 43752b8d7999ac2ebab85f28dc0c92e248b7b5fa Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Sun, 5 Jun 2016 18:50:50 +0100 Subject: Documentation: add DT bindings for ARM SCPI power domains The System Control Processor (SCP) provides peripheral devices with power domains that can be enabled and disabled viathe System Control and Power Interface (SCPI) Message Protocol. Add bindings to allow probing of these device power domians. Cc: Rob Herring Tested-by: Mathieu Poirier Tested-by: Jon Medhurst Acked-by: Mark Rutland Reviewed-by: Jon Medhurst Reviewed-by: Kevin Hilman Reviewed-by: Ulf Hansson Signed-off-by: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scpi.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt index 313dabdc14f9..faa4b44572e3 100644 --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt @@ -87,10 +87,33 @@ Required properties: implementation for the IDs to use. For Juno R0 and Juno R1 refer to [3]. +Power domain bindings for the power domains based on SCPI Message Protocol +------------------------------------------------------------ + +This binding uses the generic power domain binding[4]. + +PM domain providers +=================== + +Required properties: + - #power-domain-cells : Should be 1. Contains the device or the power + domain ID value used by SCPI commands. + - num-domains: Total number of power domains provided by SCPI. This is + needed as the SCPI message protocol lacks a mechanism to + query this information at runtime. + +PM domain consumers +=================== + +Required properties: + - power-domains : A phandle and PM domain specifier as defined by bindings of + the power controller specified by phandle. + [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html [1] Documentation/devicetree/bindings/clock/clock-bindings.txt [2] Documentation/devicetree/bindings/thermal/thermal.txt [3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html +[4] Documentation/devicetree/bindings/power/power_domain.txt Example: @@ -144,6 +167,12 @@ scpi_protocol: scpi@2e000000 { compatible = "arm,scpi-sensors"; #thermal-sensor-cells = <1>; }; + + scpi_devpd: scpi-power-domains { + compatible = "arm,scpi-power-domains"; + num-domains = <2>; + #power-domain-cells = <1>; + }; }; cpu@0 { @@ -156,6 +185,7 @@ hdlcd@7ff60000 { ... reg = <0 0x7ff60000 0 0x1000>; clocks = <&scpi_clk 4>; + power-domains = <&scpi_devpd 1>; }; thermal-zones { @@ -186,3 +216,7 @@ The thermal-sensors property in the soc_thermal node uses the temperature sensor provided by SCP firmware to setup a thermal zone. The ID "3" is the sensor identifier for the temperature sensor as used by the firmware. + +The num-domains property in scpi-power-domains domain specifies that +SCPI provides 2 power domains. The hdlcd node uses the power domain with +domain ID 1. -- cgit v1.3-14-g43fede From 7e42626ad3f4540143e68ba41e5e553f2715b451 Mon Sep 17 00:00:00 2001 From: Honghui Zhang Date: Wed, 8 Jun 2016 17:50:57 +0800 Subject: dt-bindings: mediatek: add descriptions for mediatek mt2701 iommu and smi This patch defines the local arbitor port IDs for mediatek SoC MT2701 and add descriptions of binding for mediatek generation one iommu and smi. Signed-off-by: Honghui Zhang Acked-by: Rob Herring Signed-off-by: Joerg Roedel --- .../devicetree/bindings/iommu/mediatek,iommu.txt | 13 +++- .../memory-controllers/mediatek,smi-common.txt | 21 +++++- .../memory-controllers/mediatek,smi-larb.txt | 4 +- include/dt-bindings/memory/mt2701-larb-port.h | 85 ++++++++++++++++++++++ 4 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 include/dt-bindings/memory/mt2701-larb-port.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt index cd1b1cd7b5c4..53c20cae309f 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt @@ -1,7 +1,9 @@ * Mediatek IOMMU Architecture Implementation - Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U) which -uses the ARM Short-Descriptor translation table format for address translation. + Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and +this M4U have two generations of HW architecture. Generation one uses flat +pagetable, and only supports 4K size page mapping. Generation two uses the +ARM Short-Descriptor translation table format for address translation. About the M4U Hardware Block Diagram, please check below: @@ -36,7 +38,9 @@ in each larb. Take a example, There are many ports like MC, PP, VLD in the video decode local arbiter, all these ports are according to the video HW. Required properties: -- compatible : must be "mediatek,mt8173-m4u". +- compatible : must be one of the following string: + "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW. + "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW. - reg : m4u register base and size. - interrupts : the interrupt of m4u. - clocks : must contain one entry for each clock-names. @@ -46,7 +50,8 @@ Required properties: according to the local arbiter index, like larb0, larb1, larb2... - iommu-cells : must be 1. This is the mtk_m4u_id according to the HW. Specifies the mtk_m4u_id as defined in - dt-binding/memory/mt8173-larb-port.h. + dt-binding/memory/mt2701-larb-port.h for mt2701 and + dt-binding/memory/mt8173-larb-port.h for mt8173 Example: iommu: iommu@10205000 { diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt index 06a83ceebba7..aa614b2d7cab 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt @@ -2,16 +2,31 @@ SMI (Smart Multimedia Interface) Common The hardware block diagram please check bindings/iommu/mediatek,iommu.txt +Mediatek SMI have two generations of HW architecture, mt8173 uses the second +generation of SMI HW while mt2701 uses the first generation HW of SMI. + +There's slight differences between the two SMI, for generation 2, the +register which control the iommu port is at each larb's register base. But +for generation 1, the register is at smi ao base(smi always on register +base). Besides that, the smi async clock should be prepared and enabled for +SMI generation 1 to transform the smi clock into emi clock domain, but that is +not needed for SMI generation 2. + Required properties: -- compatible : must be "mediatek,mt8173-smi-common" +- compatible : must be one of : + "mediatek,mt2701-smi-common" + "mediatek,mt8173-smi-common" - reg : the register and size of the SMI block. - power-domains : a phandle to the power domain of this local arbiter. - clocks : Must contain an entry for each entry in clock-names. -- clock-names : must contain 2 entries, as follows: +- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries + for generation 2 smi HW as follows: - "apb" : Advanced Peripheral Bus clock, It's the clock for setting the register. - "smi" : It's the clock for transfer data and command. - They may be the same if both source clocks are the same. + They may be the same if both source clocks are the same. + - "async" : asynchronous clock, it help transform the smi clock into the emi + clock domain, this clock is only needed by generation 1 smi HW. Example: smi_common: smi@14022000 { diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt index 55ff3b7e0bb9..21277a56e94c 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt @@ -3,7 +3,9 @@ SMI (Smart Multimedia Interface) Local Arbiter The hardware block diagram please check bindings/iommu/mediatek,iommu.txt Required properties: -- compatible : must be "mediatek,mt8173-smi-larb" +- compatible : must be one of : + "mediatek,mt8173-smi-larb" + "mediatek,mt2701-smi-larb" - reg : the register and size of this local arbiter. - mediatek,smi : a phandle to the smi_common node. - power-domains : a phandle to the power domain of this local arbiter. diff --git a/include/dt-bindings/memory/mt2701-larb-port.h b/include/dt-bindings/memory/mt2701-larb-port.h new file mode 100644 index 000000000000..78f66786da91 --- /dev/null +++ b/include/dt-bindings/memory/mt2701-larb-port.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015 MediaTek Inc. + * Author: Honghui Zhang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MT2701_LARB_PORT_H_ +#define _MT2701_LARB_PORT_H_ + +/* + * Mediatek m4u generation 1 such as mt2701 has flat m4u port numbers, + * the first port's id for larb[N] would be the last port's id of larb[N - 1] + * plus one while larb[0]'s first port number is 0. The definition of + * MT2701_M4U_ID_LARBx is following HW register spec. + * But m4u generation 2 like mt8173 have different port number, it use fixed + * offset for each larb, the first port's id for larb[N] would be (N * 32). + */ +#define LARB0_PORT_OFFSET 0 +#define LARB1_PORT_OFFSET 11 +#define LARB2_PORT_OFFSET 21 +#define LARB3_PORT_OFFSET 43 + +#define MT2701_M4U_ID_LARB0(port) ((port) + LARB0_PORT_OFFSET) +#define MT2701_M4U_ID_LARB1(port) ((port) + LARB1_PORT_OFFSET) +#define MT2701_M4U_ID_LARB2(port) ((port) + LARB2_PORT_OFFSET) + +/* Port define for larb0 */ +#define MT2701_M4U_PORT_DISP_OVL_0 MT2701_M4U_ID_LARB0(0) +#define MT2701_M4U_PORT_DISP_RDMA1 MT2701_M4U_ID_LARB0(1) +#define MT2701_M4U_PORT_DISP_RDMA MT2701_M4U_ID_LARB0(2) +#define MT2701_M4U_PORT_DISP_WDMA MT2701_M4U_ID_LARB0(3) +#define MT2701_M4U_PORT_MM_CMDQ MT2701_M4U_ID_LARB0(4) +#define MT2701_M4U_PORT_MDP_RDMA MT2701_M4U_ID_LARB0(5) +#define MT2701_M4U_PORT_MDP_WDMA MT2701_M4U_ID_LARB0(6) +#define MT2701_M4U_PORT_MDP_ROTO MT2701_M4U_ID_LARB0(7) +#define MT2701_M4U_PORT_MDP_ROTCO MT2701_M4U_ID_LARB0(8) +#define MT2701_M4U_PORT_MDP_ROTVO MT2701_M4U_ID_LARB0(9) +#define MT2701_M4U_PORT_MDP_RDMA1 MT2701_M4U_ID_LARB0(10) + +/* Port define for larb1 */ +#define MT2701_M4U_PORT_VDEC_MC_EXT MT2701_M4U_ID_LARB1(0) +#define MT2701_M4U_PORT_VDEC_PP_EXT MT2701_M4U_ID_LARB1(1) +#define MT2701_M4U_PORT_VDEC_PPWRAP_EXT MT2701_M4U_ID_LARB1(2) +#define MT2701_M4U_PORT_VDEC_AVC_MV_EXT MT2701_M4U_ID_LARB1(3) +#define MT2701_M4U_PORT_VDEC_PRED_RD_EXT MT2701_M4U_ID_LARB1(4) +#define MT2701_M4U_PORT_VDEC_PRED_WR_EXT MT2701_M4U_ID_LARB1(5) +#define MT2701_M4U_PORT_VDEC_VLD_EXT MT2701_M4U_ID_LARB1(6) +#define MT2701_M4U_PORT_VDEC_VLD2_EXT MT2701_M4U_ID_LARB1(7) +#define MT2701_M4U_PORT_VDEC_TILE_EXT MT2701_M4U_ID_LARB1(8) +#define MT2701_M4U_PORT_VDEC_IMG_RESZ_EXT MT2701_M4U_ID_LARB1(9) + +/* Port define for larb2 */ +#define MT2701_M4U_PORT_VENC_RCPU MT2701_M4U_ID_LARB2(0) +#define MT2701_M4U_PORT_VENC_REC_FRM MT2701_M4U_ID_LARB2(1) +#define MT2701_M4U_PORT_VENC_BSDMA MT2701_M4U_ID_LARB2(2) +#define MT2701_M4U_PORT_JPGENC_RDMA MT2701_M4U_ID_LARB2(3) +#define MT2701_M4U_PORT_VENC_LT_RCPU MT2701_M4U_ID_LARB2(4) +#define MT2701_M4U_PORT_VENC_LT_REC_FRM MT2701_M4U_ID_LARB2(5) +#define MT2701_M4U_PORT_VENC_LT_BSDMA MT2701_M4U_ID_LARB2(6) +#define MT2701_M4U_PORT_JPGDEC_BSDMA MT2701_M4U_ID_LARB2(7) +#define MT2701_M4U_PORT_VENC_SV_COMV MT2701_M4U_ID_LARB2(8) +#define MT2701_M4U_PORT_VENC_RD_COMV MT2701_M4U_ID_LARB2(9) +#define MT2701_M4U_PORT_JPGENC_BSDMA MT2701_M4U_ID_LARB2(10) +#define MT2701_M4U_PORT_VENC_CUR_LUMA MT2701_M4U_ID_LARB2(11) +#define MT2701_M4U_PORT_VENC_CUR_CHROMA MT2701_M4U_ID_LARB2(12) +#define MT2701_M4U_PORT_VENC_REF_LUMA MT2701_M4U_ID_LARB2(13) +#define MT2701_M4U_PORT_VENC_REF_CHROMA MT2701_M4U_ID_LARB2(14) +#define MT2701_M4U_PORT_IMG_RESZ MT2701_M4U_ID_LARB2(15) +#define MT2701_M4U_PORT_VENC_LT_SV_COMV MT2701_M4U_ID_LARB2(16) +#define MT2701_M4U_PORT_VENC_LT_RD_COMV MT2701_M4U_ID_LARB2(17) +#define MT2701_M4U_PORT_VENC_LT_CUR_LUMA MT2701_M4U_ID_LARB2(18) +#define MT2701_M4U_PORT_VENC_LT_CUR_CHROMA MT2701_M4U_ID_LARB2(19) +#define MT2701_M4U_PORT_VENC_LT_REF_LUMA MT2701_M4U_ID_LARB2(20) +#define MT2701_M4U_PORT_VENC_LT_REF_CHROMA MT2701_M4U_ID_LARB2(21) +#define MT2701_M4U_PORT_JPGDEC_WDMA MT2701_M4U_ID_LARB2(22) + +#endif -- cgit v1.3-14-g43fede From 00c698e09e6b8d1008d0686330c6ec3904ea6bb2 Mon Sep 17 00:00:00 2001 From: Sricharan R Date: Mon, 13 Jun 2016 17:06:03 +0530 Subject: documentation: iommu: Add bindings for msm,iommu-v0 ip The MSM IOMMU is an implementation compatible with the ARM VMSA short descriptor page tables. It provides address translation for bus masters outside of the CPU, each connected to the IOMMU through a port called micro-TLB. Adding the DT bindings for the same. Signed-off-by: Sricharan R Acked-by: Rob Herring Signed-off-by: Joerg Roedel --- .../devicetree/bindings/iommu/msm,iommu-v0.txt | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt b/Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt new file mode 100644 index 000000000000..20236385f26e --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt @@ -0,0 +1,64 @@ +* QCOM IOMMU + +The MSM IOMMU is an implementation compatible with the ARM VMSA short +descriptor page tables. It provides address translation for bus masters outside +of the CPU, each connected to the IOMMU through a port called micro-TLB. + +Required Properties: + + - compatible: Must contain "qcom,apq8064-iommu". + - reg: Base address and size of the IOMMU registers. + - interrupts: Specifiers for the MMU fault interrupts. For instances that + support secure mode two interrupts must be specified, for non-secure and + secure mode, in that order. For instances that don't support secure mode a + single interrupt must be specified. + - #iommu-cells: The number of cells needed to specify the stream id. This + is always 1. + - qcom,ncb: The total number of context banks in the IOMMU. + - clocks : List of clocks to be used during SMMU register access. See + Documentation/devicetree/bindings/clock/clock-bindings.txt + for information about the format. For each clock specified + here, there must be a corresponding entry in clock-names + (see below). + + - clock-names : List of clock names corresponding to the clocks specified in + the "clocks" property (above). + Should be "smmu_pclk" for specifying the interface clock + required for iommu's register accesses. + Should be "smmu_clk" for specifying the functional clock + required by iommu for bus accesses. + +Each bus master connected to an IOMMU must reference the IOMMU in its device +node with the following property: + + - iommus: A reference to the IOMMU in multiple cells. The first cell is a + phandle to the IOMMU and the second cell is the stream id. + A single master device can be connected to more than one iommu + and multiple contexts in each of the iommu. So multiple entries + are required to list all the iommus and the stream ids that the + master is connected to. + +Example: mdp iommu and its bus master + + mdp_port0: iommu@7500000 { + compatible = "qcom,apq8064-iommu"; + #iommu-cells = <1>; + clock-names = + "smmu_pclk", + "smmu_clk"; + clocks = + <&mmcc SMMU_AHB_CLK>, + <&mmcc MDP_AXI_CLK>; + reg = <0x07500000 0x100000>; + interrupts = + , + ; + qcom,ncb = <2>; + }; + + mdp: qcom,mdp@5100000 { + compatible = "qcom,mdp"; + ... + iommus = <&mdp_port0 0 + &mdp_port0 2>; + }; -- cgit v1.3-14-g43fede From cb597fcea5c2835f7faef77c0d0ed5016566cca2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Jun 2016 14:48:57 +0300 Subject: Documentation/gpu: add new gpu.rst converted from DocBook gpu.tmpl This is the first step towards converting the DocBook gpu.tmpl to Sphinx and reStructuredText, the new kernel documentation tool and markup. Use Jon's "cheesy conversion script" in Documentation/sphinx/tmplcvt to do the rough conversion. Do the manual edits in follow-up patches. Add a new Documentation/gpu directories for the graphics related documentation. (Hooray, now we can have directories based on topics rather than tools under Documentation.) We also won't remove the DocBook gpu.tmpl yet so it's easier to build both and compare the results for parity. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/bc7b4f9ac037632e0c8469c079d21fad5eaa39a0.1466506505.git.jani.nikula@intel.com --- Documentation/gpu/index.rst | 2601 +++++++++++++++++++++++++++++++++++++++++++ Documentation/index.rst | 1 + 2 files changed, 2602 insertions(+) create mode 100644 Documentation/gpu/index.rst (limited to 'Documentation') diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst new file mode 100644 index 000000000000..795a5ec309e2 --- /dev/null +++ b/Documentation/gpu/index.rst @@ -0,0 +1,2601 @@ +================================== +Linux GPU Driver Developer's Guide +================================== + +:Author: Jesse Barnes Initial version +:Author: Laurent Pinchart Driver internals +:Author: Daniel Vetter Contributions all over the place +:Author: Lukas Wunner vga_switcheroo documentation +:Date: 2015-10-11 + +This first part of the GPU Driver Developer's Guide documents core DRM +code, helper libraries for writing drivers and generic userspace +interfaces exposed by DRM drivers. + +Introduction +============ + +The Linux DRM layer contains code intended to support the needs of +complex graphics devices, usually containing programmable pipelines well +suited to 3D graphics acceleration. Graphics drivers in the kernel may +make use of DRM functions to make tasks like memory management, +interrupt handling and DMA easier, and provide a uniform interface to +applications. + +A note on versions: this guide covers features found in the DRM tree, +including the TTM memory manager, output configuration and mode setting, +and the new vblank internals, in addition to all the regular features +found in current kernels. + +[Insert diagram of typical DRM stack here] + +Style Guidelines +---------------- + +For consistency this documentation uses American English. Abbreviations +are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so +on. To aid in reading, documentations make full use of the markup +characters kerneldoc provides: @parameter for function parameters, +@member for structure members, &structure to reference structures and +function() for functions. These all get automatically hyperlinked if +kerneldoc for the referenced objects exists. When referencing entries in +function vtables please use ->vfunc(). Note that kerneldoc does not +support referencing struct members directly, so please add a reference +to the vtable struct somewhere in the same paragraph or at least +section. + +Except in special situations (to separate locked from unlocked variants) +locking requirements for functions aren't documented in the kerneldoc. +Instead locking should be check at runtime using e.g. +``WARN_ON(!mutex_is_locked(...));``. Since it's much easier to ignore +documentation than runtime noise this provides more value. And on top of +that runtime checks do need to be updated when the locking rules change, +increasing the chances that they're correct. Within the documentation +the locking rules should be explained in the relevant structures: Either +in the comment for the lock explaining what it protects, or data fields +need a note about which lock protects them, or both. + +Functions which have a non-\ ``void`` return value should have a section +called "Returns" explaining the expected return values in different +cases and their meanings. Currently there's no consensus whether that +section name should be all upper-case or not, and whether it should end +in a colon or not. Go with the file-local style. Other common section +names are "Notes" with information for dangerous or tricky corner cases, +and "FIXME" where the interface could be cleaned up. + +DRM Internals +============= + +This chapter documents DRM internals relevant to driver authors and +developers working to add support for the latest features to existing +drivers. + +First, we go over some typical driver initialization requirements, like +setting up command buffers, creating an initial output configuration, +and initializing core services. Subsequent sections cover core internals +in more detail, providing implementation notes and examples. + +The DRM layer provides several services to graphics drivers, many of +them driven by the application interfaces it provides through libdrm, +the library that wraps most of the DRM ioctls. These include vblank +event handling, memory management, output management, framebuffer +management, command submission & fencing, suspend/resume support, and +DMA services. + +Driver Initialization +--------------------- + +At the core of every DRM driver is a :c:type:`struct drm_driver +` structure. Drivers typically statically initialize +a drm_driver structure, and then pass it to +:c:func:`drm_dev_alloc()` to allocate a device instance. After the +device instance is fully initialized it can be registered (which makes +it accessible from userspace) using :c:func:`drm_dev_register()`. + +The :c:type:`struct drm_driver ` structure +contains static information that describes the driver and features it +supports, and pointers to methods that the DRM core will call to +implement the DRM API. We will first go through the :c:type:`struct +drm_driver ` static information fields, and will +then describe individual operations in details as they get used in later +sections. + +Driver Information +~~~~~~~~~~~~~~~~~~ + +Driver Features +^^^^^^^^^^^^^^^ + +Drivers inform the DRM core about their requirements and supported +features by setting appropriate flags in the driver_features field. +Since those flags influence the DRM core behaviour since registration +time, most of them must be set to registering the :c:type:`struct +drm_driver ` instance. + +u32 driver_features; + +DRIVER_USE_AGP + Driver uses AGP interface, the DRM core will manage AGP resources. + +DRIVER_REQUIRE_AGP + Driver needs AGP interface to function. AGP initialization failure + will become a fatal error. + +DRIVER_PCI_DMA + Driver is capable of PCI DMA, mapping of PCI DMA buffers to + userspace will be enabled. Deprecated. + +DRIVER_SG + Driver can perform scatter/gather DMA, allocation and mapping of + scatter/gather buffers will be enabled. Deprecated. + +DRIVER_HAVE_DMA + Driver supports DMA, the userspace DMA API will be supported. + Deprecated. + +DRIVER_HAVE_IRQ; DRIVER_IRQ_SHARED + DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler + managed by the DRM Core. The core will support simple IRQ handler + installation when the flag is set. The installation process is + described in ?. + + DRIVER_IRQ_SHARED indicates whether the device & handler support + shared IRQs (note that this is required of PCI drivers). + +DRIVER_GEM + Driver use the GEM memory manager. + +DRIVER_MODESET + Driver supports mode setting interfaces (KMS). + +DRIVER_PRIME + Driver implements DRM PRIME buffer sharing. + +DRIVER_RENDER + Driver supports dedicated render nodes. + +DRIVER_ATOMIC + Driver supports atomic properties. In this case the driver must + implement appropriate obj->atomic_get_property() vfuncs for any + modeset objects with driver specific properties. + +Major, Minor and Patchlevel +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +int major; int minor; int patchlevel; +The DRM core identifies driver versions by a major, minor and patch +level triplet. The information is printed to the kernel log at +initialization time and passed to userspace through the +DRM_IOCTL_VERSION ioctl. + +The major and minor numbers are also used to verify the requested driver +API version passed to DRM_IOCTL_SET_VERSION. When the driver API +changes between minor versions, applications can call +DRM_IOCTL_SET_VERSION to select a specific version of the API. If the +requested major isn't equal to the driver major, or the requested minor +is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will +return an error. Otherwise the driver's set_version() method will be +called with the requested version. + +Name, Description and Date +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +char \*name; char \*desc; char \*date; +The driver name is printed to the kernel log at initialization time, +used for IRQ registration and passed to userspace through +DRM_IOCTL_VERSION. + +The driver description is a purely informative string passed to +userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by +the kernel. + +The driver date, formatted as YYYYMMDD, is meant to identify the date of +the latest modification to the driver. However, as most drivers fail to +update it, its value is mostly useless. The DRM core prints it to the +kernel log at initialization time and passes it to userspace through the +DRM_IOCTL_VERSION ioctl. + +Device Instance and Driver Handling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_drv.c + :doc: driver instance overview + +.. kernel-doc:: drivers/gpu/drm/drm_drv.c + :export: + +Driver Load +~~~~~~~~~~~ + +IRQ Registration +^^^^^^^^^^^^^^^^ + +The DRM core tries to facilitate IRQ handler registration and +unregistration by providing :c:func:`drm_irq_install()` and +:c:func:`drm_irq_uninstall()` functions. Those functions only +support a single interrupt per device, devices that use more than one +IRQs need to be handled manually. + +Managed IRQ Registration +'''''''''''''''''''''''' + +:c:func:`drm_irq_install()` starts by calling the irq_preinstall +driver operation. The operation is optional and must make sure that the +interrupt will not get fired by clearing all pending interrupt flags or +disabling the interrupt. + +The passed-in IRQ will then be requested by a call to +:c:func:`request_irq()`. If the DRIVER_IRQ_SHARED driver feature +flag is set, a shared (IRQF_SHARED) IRQ handler will be requested. + +The IRQ handler function must be provided as the mandatory irq_handler +driver operation. It will get passed directly to +:c:func:`request_irq()` and thus has the same prototype as all IRQ +handlers. It will get called with a pointer to the DRM device as the +second argument. + +Finally the function calls the optional irq_postinstall driver +operation. The operation usually enables interrupts (excluding the +vblank interrupt, which is enabled separately), but drivers may choose +to enable/disable interrupts at a different time. + +:c:func:`drm_irq_uninstall()` is similarly used to uninstall an +IRQ handler. It starts by waking up all processes waiting on a vblank +interrupt to make sure they don't hang, and then calls the optional +irq_uninstall driver operation. The operation must disable all hardware +interrupts. Finally the function frees the IRQ by calling +:c:func:`free_irq()`. + +Manual IRQ Registration +''''''''''''''''''''''' + +Drivers that require multiple interrupt handlers can't use the managed +IRQ registration functions. In that case IRQs must be registered and +unregistered manually (usually with the :c:func:`request_irq()` and +:c:func:`free_irq()` functions, or their devm_\* equivalent). + +When manually registering IRQs, drivers must not set the +DRIVER_HAVE_IRQ driver feature flag, and must not provide the +irq_handler driver operation. They must set the :c:type:`struct +drm_device ` irq_enabled field to 1 upon +registration of the IRQs, and clear it to 0 after unregistering the +IRQs. + +Memory Manager Initialization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Every DRM driver requires a memory manager which must be initialized at +load time. DRM currently contains two memory managers, the Translation +Table Manager (TTM) and the Graphics Execution Manager (GEM). This +document describes the use of the GEM memory manager only. See ? for +details. + +Miscellaneous Device Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Another task that may be necessary for PCI devices during configuration +is mapping the video BIOS. On many devices, the VBIOS describes device +configuration, LCD panel timings (if any), and contains flags indicating +device state. Mapping the BIOS can be done using the pci_map_rom() +call, a convenience function that takes care of mapping the actual ROM, +whether it has been shadowed into memory (typically at address 0xc0000) +or exists on the PCI device in the ROM BAR. Note that after the ROM has +been mapped and any necessary information has been extracted, it should +be unmapped; on many devices, the ROM address decoder is shared with +other BARs, so leaving it mapped could cause undesired behaviour like +hangs or memory corruption. + +Bus-specific Device Registration and PCI Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A number of functions are provided to help with device registration. The +functions deal with PCI and platform devices respectively and are only +provided for historical reasons. These are all deprecated and shouldn't +be used in new drivers. Besides that there's a few helpers for pci +drivers. + +.. kernel-doc:: drivers/gpu/drm/drm_pci.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_platform.c + :export: + +Memory management +----------------- + +Modern Linux systems require large amount of graphics memory to store +frame buffers, textures, vertices and other graphics-related data. Given +the very dynamic nature of many of that data, managing graphics memory +efficiently is thus crucial for the graphics stack and plays a central +role in the DRM infrastructure. + +The DRM core includes two memory managers, namely Translation Table Maps +(TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory +manager to be developed and tried to be a one-size-fits-them all +solution. It provides a single userspace API to accommodate the need of +all hardware, supporting both Unified Memory Architecture (UMA) devices +and devices with dedicated video RAM (i.e. most discrete video cards). +This resulted in a large, complex piece of code that turned out to be +hard to use for driver development. + +GEM started as an Intel-sponsored project in reaction to TTM's +complexity. Its design philosophy is completely different: instead of +providing a solution to every graphics memory-related problems, GEM +identified common code between drivers and created a support library to +share it. GEM has simpler initialization and execution requirements than +TTM, but has no video RAM management capabilities and is thus limited to +UMA devices. + +The Translation Table Manager (TTM) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +TTM design background and information belongs here. + +TTM initialization +^^^^^^^^^^^^^^^^^^ + + **Warning** + + This section is outdated. + +Drivers wishing to support TTM must fill out a drm_bo_driver +structure. The structure contains several fields with function pointers +for initializing the TTM, allocating and freeing memory, waiting for +command completion and fence synchronization, and memory migration. See +the radeon_ttm.c file for an example of usage. + +The ttm_global_reference structure is made up of several fields: + +:: + + struct ttm_global_reference { + enum ttm_global_types global_type; + size_t size; + void *object; + int (*init) (struct ttm_global_reference *); + void (*release) (struct ttm_global_reference *); + }; + + +There should be one global reference structure for your memory manager +as a whole, and there will be others for each object created by the +memory manager at runtime. Your global TTM should have a type of +TTM_GLOBAL_TTM_MEM. The size field for the global object should be +sizeof(struct ttm_mem_global), and the init and release hooks should +point at your driver-specific init and release routines, which probably +eventually call ttm_mem_global_init and ttm_mem_global_release, +respectively. + +Once your global TTM accounting structure is set up and initialized by +calling ttm_global_item_ref() on it, you need to create a buffer +object TTM to provide a pool for buffer object allocation by clients and +the kernel itself. The type of this object should be +TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct +ttm_bo_global). Again, driver-specific init and release functions may +be provided, likely eventually calling ttm_bo_global_init() and +ttm_bo_global_release(), respectively. Also, like the previous +object, ttm_global_item_ref() is used to create an initial reference +count for the TTM, which will call your initialization function. + +The Graphics Execution Manager (GEM) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The GEM design approach has resulted in a memory manager that doesn't +provide full coverage of all (or even all common) use cases in its +userspace or kernel API. GEM exposes a set of standard memory-related +operations to userspace and a set of helper functions to drivers, and +let drivers implement hardware-specific operations with their own +private API. + +The GEM userspace API is described in the `GEM - the Graphics Execution +Manager `__ article on LWN. While +slightly outdated, the document provides a good overview of the GEM API +principles. Buffer allocation and read and write operations, described +as part of the common GEM API, are currently implemented using +driver-specific ioctls. + +GEM is data-agnostic. It manages abstract buffer objects without knowing +what individual buffers contain. APIs that require knowledge of buffer +contents or purpose, such as buffer allocation or synchronization +primitives, are thus outside of the scope of GEM and must be implemented +using driver-specific ioctls. + +On a fundamental level, GEM involves several operations: + +- Memory allocation and freeing +- Command execution +- Aperture management at command execution time + +Buffer object allocation is relatively straightforward and largely +provided by Linux's shmem layer, which provides memory to back each +object. + +Device-specific operations, such as command execution, pinning, buffer +read & write, mapping, and domain ownership transfers are left to +driver-specific ioctls. + +GEM Initialization +^^^^^^^^^^^^^^^^^^ + +Drivers that use GEM must set the DRIVER_GEM bit in the struct +:c:type:`struct drm_driver ` driver_features +field. The DRM core will then automatically initialize the GEM core +before calling the load operation. Behind the scene, this will create a +DRM Memory Manager object which provides an address space pool for +object allocation. + +In a KMS configuration, drivers need to allocate and initialize a +command ring buffer following core GEM initialization if required by the +hardware. UMA devices usually have what is called a "stolen" memory +region, which provides space for the initial framebuffer and large, +contiguous memory regions required by the device. This space is +typically not managed by GEM, and must be initialized separately into +its own DRM MM object. + +GEM Objects Creation +^^^^^^^^^^^^^^^^^^^^ + +GEM splits creation of GEM objects and allocation of the memory that +backs them in two distinct operations. + +GEM objects are represented by an instance of struct :c:type:`struct +drm_gem_object `. Drivers usually need to +extend GEM objects with private information and thus create a +driver-specific GEM object structure type that embeds an instance of +struct :c:type:`struct drm_gem_object `. + +To create a GEM object, a driver allocates memory for an instance of its +specific GEM object type and initializes the embedded struct +:c:type:`struct drm_gem_object ` with a call +to :c:func:`drm_gem_object_init()`. The function takes a pointer +to the DRM device, a pointer to the GEM object and the buffer object +size in bytes. + +GEM uses shmem to allocate anonymous pageable memory. +:c:func:`drm_gem_object_init()` will create an shmfs file of the +requested size and store it into the struct :c:type:`struct +drm_gem_object ` filp field. The memory is +used as either main storage for the object when the graphics hardware +uses system memory directly or as a backing store otherwise. + +Drivers are responsible for the actual physical pages allocation by +calling :c:func:`shmem_read_mapping_page_gfp()` for each page. +Note that they can decide to allocate pages when initializing the GEM +object, or to delay allocation until the memory is needed (for instance +when a page fault occurs as a result of a userspace memory access or +when the driver needs to start a DMA transfer involving the memory). + +Anonymous pageable memory allocation is not always desired, for instance +when the hardware requires physically contiguous system memory as is +often the case in embedded devices. Drivers can create GEM objects with +no shmfs backing (called private GEM objects) by initializing them with +a call to :c:func:`drm_gem_private_object_init()` instead of +:c:func:`drm_gem_object_init()`. Storage for private GEM objects +must be managed by drivers. + +GEM Objects Lifetime +^^^^^^^^^^^^^^^^^^^^ + +All GEM objects are reference-counted by the GEM core. References can be +acquired and release by :c:func:`calling +drm_gem_object_reference()` and +:c:func:`drm_gem_object_unreference()` respectively. The caller +must hold the :c:type:`struct drm_device ` +struct_mutex lock when calling +:c:func:`drm_gem_object_reference()`. As a convenience, GEM +provides :c:func:`drm_gem_object_unreference_unlocked()` +functions that can be called without holding the lock. + +When the last reference to a GEM object is released the GEM core calls +the :c:type:`struct drm_driver ` gem_free_object +operation. That operation is mandatory for GEM-enabled drivers and must +free the GEM object and all associated resources. + +void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are +responsible for freeing all GEM object resources. This includes the +resources created by the GEM core, which need to be released with +:c:func:`drm_gem_object_release()`. + +GEM Objects Naming +^^^^^^^^^^^^^^^^^^ + +Communication between userspace and the kernel refers to GEM objects +using local handles, global names or, more recently, file descriptors. +All of those are 32-bit integer values; the usual Linux kernel limits +apply to the file descriptors. + +GEM handles are local to a DRM file. Applications get a handle to a GEM +object through a driver-specific ioctl, and can use that handle to refer +to the GEM object in other standard or driver-specific ioctls. Closing a +DRM file handle frees all its GEM handles and dereferences the +associated GEM objects. + +To create a handle for a GEM object drivers call +:c:func:`drm_gem_handle_create()`. The function takes a pointer +to the DRM file and the GEM object and returns a locally unique handle. +When the handle is no longer needed drivers delete it with a call to +:c:func:`drm_gem_handle_delete()`. Finally the GEM object +associated with a handle can be retrieved by a call to +:c:func:`drm_gem_object_lookup()`. + +Handles don't take ownership of GEM objects, they only take a reference +to the object that will be dropped when the handle is destroyed. To +avoid leaking GEM objects, drivers must make sure they drop the +reference(s) they own (such as the initial reference taken at object +creation time) as appropriate, without any special consideration for the +handle. For example, in the particular case of combined GEM object and +handle creation in the implementation of the dumb_create operation, +drivers must drop the initial reference to the GEM object before +returning the handle. + +GEM names are similar in purpose to handles but are not local to DRM +files. They can be passed between processes to reference a GEM object +globally. Names can't be used directly to refer to objects in the DRM +API, applications must convert handles to names and names to handles +using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls +respectively. The conversion is handled by the DRM core without any +driver-specific support. + +GEM also supports buffer sharing with dma-buf file descriptors through +PRIME. GEM-based drivers must use the provided helpers functions to +implement the exporting and importing correctly. See ?. Since sharing +file descriptors is inherently more secure than the easily guessable and +global GEM names it is the preferred buffer sharing mechanism. Sharing +buffers through GEM names is only supported for legacy userspace. +Furthermore PRIME also allows cross-device buffer sharing since it is +based on dma-bufs. + +GEM Objects Mapping +^^^^^^^^^^^^^^^^^^^ + +Because mapping operations are fairly heavyweight GEM favours +read/write-like access to buffers, implemented through driver-specific +ioctls, over mapping buffers to userspace. However, when random access +to the buffer is needed (to perform software rendering for instance), +direct access to the object can be more efficient. + +The mmap system call can't be used directly to map GEM objects, as they +don't have their own file handle. Two alternative methods currently +co-exist to map GEM objects to userspace. The first method uses a +driver-specific ioctl to perform the mapping operation, calling +:c:func:`do_mmap()` under the hood. This is often considered +dubious, seems to be discouraged for new GEM-enabled drivers, and will +thus not be described here. + +The second method uses the mmap system call on the DRM file handle. void +\*mmap(void \*addr, size_t length, int prot, int flags, int fd, off_t +offset); DRM identifies the GEM object to be mapped by a fake offset +passed through the mmap offset argument. Prior to being mapped, a GEM +object must thus be associated with a fake offset. To do so, drivers +must call :c:func:`drm_gem_create_mmap_offset()` on the object. + +Once allocated, the fake offset value must be passed to the application +in a driver-specific way and can then be used as the mmap offset +argument. + +The GEM core provides a helper method :c:func:`drm_gem_mmap()` to +handle object mapping. The method can be set directly as the mmap file +operation handler. It will look up the GEM object based on the offset +value and set the VMA operations to the :c:type:`struct drm_driver +` gem_vm_ops field. Note that +:c:func:`drm_gem_mmap()` doesn't map memory to userspace, but +relies on the driver-provided fault handler to map pages individually. + +To use :c:func:`drm_gem_mmap()`, drivers must fill the struct +:c:type:`struct drm_driver ` gem_vm_ops field +with a pointer to VM operations. + +struct vm_operations_struct \*gem_vm_ops struct +vm_operations_struct { void (\*open)(struct vm_area_struct \* area); +void (\*close)(struct vm_area_struct \* area); int (\*fault)(struct +vm_area_struct \*vma, struct vm_fault \*vmf); }; + +The open and close operations must update the GEM object reference +count. Drivers can use the :c:func:`drm_gem_vm_open()` and +:c:func:`drm_gem_vm_close()` helper functions directly as open +and close handlers. + +The fault operation handler is responsible for mapping individual pages +to userspace when a page fault occurs. Depending on the memory +allocation scheme, drivers can allocate pages at fault time, or can +decide to allocate memory for the GEM object at the time the object is +created. + +Drivers that want to map the GEM object upfront instead of handling page +faults can implement their own mmap file operation handler. + +Memory Coherency +^^^^^^^^^^^^^^^^ + +When mapped to the device or used in a command buffer, backing pages for +an object are flushed to memory and marked write combined so as to be +coherent with the GPU. Likewise, if the CPU accesses an object after the +GPU has finished rendering to the object, then the object must be made +coherent with the CPU's view of memory, usually involving GPU cache +flushing of various kinds. This core CPU<->GPU coherency management is +provided by a device-specific ioctl, which evaluates an object's current +domain and performs any necessary flushing or synchronization to put the +object into the desired coherency domain (note that the object may be +busy, i.e. an active render target; in that case, setting the domain +blocks the client and waits for rendering to complete before performing +any necessary flushing operations). + +Command Execution +^^^^^^^^^^^^^^^^^ + +Perhaps the most important GEM function for GPU devices is providing a +command execution interface to clients. Client programs construct +command buffers containing references to previously allocated memory +objects, and then submit them to GEM. At that point, GEM takes care to +bind all the objects into the GTT, execute the buffer, and provide +necessary synchronization between clients accessing the same buffers. +This often involves evicting some objects from the GTT and re-binding +others (a fairly expensive operation), and providing relocation support +which hides fixed GTT offsets from clients. Clients must take care not +to submit command buffers that reference more objects than can fit in +the GTT; otherwise, GEM will reject them and no rendering will occur. +Similarly, if several objects in the buffer require fence registers to +be allocated for correct rendering (e.g. 2D blits on pre-965 chips), +care must be taken not to require more fence registers than are +available to the client. Such resource management should be abstracted +from the client in libdrm. + +GEM Function Reference +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_gem.c + :export: + +.. kernel-doc:: include/drm/drm_gem.h + :internal: + +VMA Offset Manager +~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :doc: vma offset manager + +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :export: + +.. kernel-doc:: include/drm/drm_vma_manager.h + :internal: + +PRIME Buffer Sharing +~~~~~~~~~~~~~~~~~~~~ + +PRIME is the cross device buffer sharing framework in drm, originally +created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME +buffers are dma-buf based file descriptors. + +Overview and Driver Interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Similar to GEM global names, PRIME file descriptors are also used to +share buffer objects across processes. They offer additional security: +as file descriptors must be explicitly sent over UNIX domain sockets to +be shared between applications, they can't be guessed like the globally +unique GEM names. + +Drivers that support the PRIME API must set the DRIVER_PRIME bit in the +struct :c:type:`struct drm_driver ` +driver_features field, and implement the prime_handle_to_fd and +prime_fd_to_handle operations. + +int (\*prime_handle_to_fd)(struct drm_device \*dev, struct drm_file +\*file_priv, uint32_t handle, uint32_t flags, int \*prime_fd); int +(\*prime_fd_to_handle)(struct drm_device \*dev, struct drm_file +\*file_priv, int prime_fd, uint32_t \*handle); Those two operations +convert a handle to a PRIME file descriptor and vice versa. Drivers must +use the kernel dma-buf buffer sharing framework to manage the PRIME file +descriptors. Similar to the mode setting API PRIME is agnostic to the +underlying buffer object manager, as long as handles are 32bit unsigned +integers. + +While non-GEM drivers must implement the operations themselves, GEM +drivers must use the :c:func:`drm_gem_prime_handle_to_fd()` and +:c:func:`drm_gem_prime_fd_to_handle()` helper functions. Those +helpers rely on the driver gem_prime_export and gem_prime_import +operations to create a dma-buf instance from a GEM object (dma-buf +exporter role) and to create a GEM object from a dma-buf instance +(dma-buf importer role). + +struct dma_buf \* (\*gem_prime_export)(struct drm_device \*dev, +struct drm_gem_object \*obj, int flags); struct drm_gem_object \* +(\*gem_prime_import)(struct drm_device \*dev, struct dma_buf +\*dma_buf); These two operations are mandatory for GEM drivers that +support PRIME. + +PRIME Helper Functions +^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_prime.c + :doc: PRIME Helpers + +PRIME Function References +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_prime.c + :export: + +DRM MM Range Allocator +~~~~~~~~~~~~~~~~~~~~~~ + +Overview +^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :doc: Overview + +LRU Scan/Eviction Support +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :doc: lru scan roaster + +DRM MM Range Allocator Function References +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :export: + +.. kernel-doc:: include/drm/drm_mm.h + :internal: + +CMA Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :doc: cma helpers + +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :export: + +.. kernel-doc:: include/drm/drm_gem_cma_helper.h + :internal: + +Mode Setting +------------ + +Drivers must initialize the mode setting core by calling +:c:func:`drm_mode_config_init()` on the DRM device. The function +initializes the :c:type:`struct drm_device ` +mode_config field and never fails. Once done, mode configuration must +be setup by initializing the following fields. + +- int min_width, min_height; int max_width, max_height; + Minimum and maximum width and height of the frame buffers in pixel + units. + +- struct drm_mode_config_funcs \*funcs; + Mode setting functions. + +Display Modes Function Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_modes.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_modes.c + :export: + +Atomic Mode Setting Function Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :internal: + +Frame Buffer Abstraction +~~~~~~~~~~~~~~~~~~~~~~~~ + +Frame buffers are abstract memory objects that provide a source of +pixels to scanout to a CRTC. Applications explicitly request the +creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls +and receive an opaque handle that can be passed to the KMS CRTC control, +plane configuration and page flip functions. + +Frame buffers rely on the underneath memory manager for low-level memory +operations. When creating a frame buffer applications pass a memory +handle (or a list of memory handles for multi-planar formats) through +the ``drm_mode_fb_cmd2`` argument. For drivers using GEM as their +userspace buffer management interface this would be a GEM handle. +Drivers are however free to use their own backing storage object +handles, e.g. vmwgfx directly exposes special TTM handles to userspace +and so expects TTM handles in the create ioctl and not GEM handles. + +The lifetime of a drm framebuffer is controlled with a reference count, +drivers can grab additional references with +:c:func:`drm_framebuffer_reference()`and drop them again with +:c:func:`drm_framebuffer_unreference()`. For driver-private +framebuffers for which the last reference is never dropped (e.g. for the +fbdev framebuffer when the struct :c:type:`struct drm_framebuffer +` is embedded into the fbdev helper struct) +drivers can manually clean up a framebuffer at module unload time with +:c:func:`drm_framebuffer_unregister_private()`. + +DRM Format Handling +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_fourcc.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c + :export: + +Dumb Buffer Objects +~~~~~~~~~~~~~~~~~~~ + +The KMS API doesn't standardize backing storage object creation and +leaves it to driver-specific ioctls. Furthermore actually creating a +buffer object even for GEM-based drivers is done through a +driver-specific ioctl - GEM only has a common userspace interface for +sharing and destroying objects. While not an issue for full-fledged +graphics stacks that include device-specific userspace components (in +libdrm for instance), this limit makes DRM-based early boot graphics +unnecessarily complex. + +Dumb objects partly alleviate the problem by providing a standard API to +create dumb buffers suitable for scanout, which can then be used to +create KMS frame buffers. + +To support dumb objects drivers must implement the dumb_create, +dumb_destroy and dumb_map_offset operations. + +- int (\*dumb_create)(struct drm_file \*file_priv, struct + drm_device \*dev, struct drm_mode_create_dumb \*args); + The dumb_create operation creates a driver object (GEM or TTM + handle) suitable for scanout based on the width, height and depth + from the struct :c:type:`struct drm_mode_create_dumb + ` argument. It fills the argument's + handle, pitch and size fields with a handle for the newly created + object and its line pitch and size in bytes. + +- int (\*dumb_destroy)(struct drm_file \*file_priv, struct + drm_device \*dev, uint32_t handle); + The dumb_destroy operation destroys a dumb object created by + dumb_create. + +- int (\*dumb_map_offset)(struct drm_file \*file_priv, struct + drm_device \*dev, uint32_t handle, uint64_t \*offset); + The dumb_map_offset operation associates an mmap fake offset with + the object given by the handle and returns it. Drivers must use the + :c:func:`drm_gem_create_mmap_offset()` function to associate + the fake offset as described in ?. + +Note that dumb objects may not be used for gpu acceleration, as has been +attempted on some ARM embedded platforms. Such drivers really must have +a hardware-specific ioctl to allocate suitable buffer objects. + +Output Polling +~~~~~~~~~~~~~~ + +void (\*output_poll_changed)(struct drm_device \*dev); +This operation notifies the driver that the status of one or more +connectors has changed. Drivers that use the fb helper can just call the +:c:func:`drm_fb_helper_hotplug_event()` function to handle this +operation. + +KMS Initialization and Cleanup +------------------------------ + +A KMS device is abstracted and exposed as a set of planes, CRTCs, +encoders and connectors. KMS drivers must thus create and initialize all +those objects at load time after initializing mode setting. + +CRTCs (:c:type:`struct drm_crtc `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A CRTC is an abstraction representing a part of the chip that contains a +pointer to a scanout buffer. Therefore, the number of CRTCs available +determines how many independent scanout buffers can be active at any +given time. The CRTC structure contains several fields to support this: +a pointer to some video memory (abstracted as a frame buffer object), a +display mode, and an (x, y) offset into the video memory to support +panning or configurations where one piece of video memory spans multiple +CRTCs. + +CRTC Initialization +^^^^^^^^^^^^^^^^^^^ + +A KMS device must create and register at least one struct +:c:type:`struct drm_crtc ` instance. The instance is +allocated and zeroed by the driver, possibly as part of a larger +structure, and registered with a call to :c:func:`drm_crtc_init()` +with a pointer to CRTC functions. + +Planes (:c:type:`struct drm_plane `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A plane represents an image source that can be blended with or overlayed +on top of a CRTC during the scanout process. Planes are associated with +a frame buffer to crop a portion of the image memory (source) and +optionally scale it to a destination size. The result is then blended +with or overlayed on top of a CRTC. + +The DRM core recognizes three types of planes: + +- DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. + Primary planes are the planes operated upon by CRTC modesetting and + flipping operations described in the page_flip hook in + :c:type:`struct drm_crtc_funcs `. +- DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. + Cursor planes are the planes operated upon by the + DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls. +- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor + planes. Some drivers refer to these types of planes as "sprites" + internally. + +For compatibility with legacy userspace, only overlay planes are made +available to userspace by default. Userspace clients may set the +DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate +that they wish to receive a universal plane list containing all plane +types. + +Plane Initialization +^^^^^^^^^^^^^^^^^^^^ + +To create a plane, a KMS drivers allocates and zeroes an instances of +:c:type:`struct drm_plane ` (possibly as part of a +larger structure) and registers it with a call to +:c:func:`drm_universal_plane_init()`. The function takes a +bitmask of the CRTCs that can be associated with the plane, a pointer to +the plane functions, a list of format supported formats, and the type of +plane (primary, cursor, or overlay) being initialized. + +Cursor and overlay planes are optional. All drivers should provide one +primary plane per CRTC (although this requirement may change in the +future); drivers that do not wish to provide special handling for +primary planes may make use of the helper functions described in ? to +create and register a primary plane with standard capabilities. + +Encoders (:c:type:`struct drm_encoder `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An encoder takes pixel data from a CRTC and converts it to a format +suitable for any attached connectors. On some devices, it may be +possible to have a CRTC send data to more than one encoder. In that +case, both encoders would receive data from the same scanout buffer, +resulting in a "cloned" display configuration across the connectors +attached to each encoder. + +Encoder Initialization +^^^^^^^^^^^^^^^^^^^^^^ + +As for CRTCs, a KMS driver must create, initialize and register at least +one :c:type:`struct drm_encoder ` instance. The +instance is allocated and zeroed by the driver, possibly as part of a +larger structure. + +Drivers must initialize the :c:type:`struct drm_encoder +` possible_crtcs and possible_clones fields before +registering the encoder. Both fields are bitmasks of respectively the +CRTCs that the encoder can be connected to, and sibling encoders +candidate for cloning. + +After being initialized, the encoder must be registered with a call to +:c:func:`drm_encoder_init()`. The function takes a pointer to the +encoder functions and an encoder type. Supported types are + +- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A +- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort +- DRM_MODE_ENCODER_LVDS for display panels +- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, + Component, SCART) +- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays + +Encoders must be attached to a CRTC to be used. DRM drivers leave +encoders unattached at initialization time. Applications (or the fbdev +compatibility layer when implemented) are responsible for attaching the +encoders they want to use to a CRTC. + +Connectors (:c:type:`struct drm_connector `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A connector is the final destination for pixel data on a device, and +usually connects directly to an external display device like a monitor +or laptop panel. A connector can only be attached to one encoder at a +time. The connector is also the structure where information about the +attached display is kept, so it contains fields for display data, EDID +data, DPMS & connection status, and information about modes supported on +the attached displays. + +Connector Initialization +^^^^^^^^^^^^^^^^^^^^^^^^ + +Finally a KMS driver must create, initialize, register and attach at +least one :c:type:`struct drm_connector ` +instance. The instance is created as other KMS objects and initialized +by setting the following fields. + +interlace_allowed + Whether the connector can handle interlaced modes. + +doublescan_allowed + Whether the connector can handle doublescan. + +display_info + Display information is filled from EDID information when a display + is detected. For non hot-pluggable displays such as flat panels in + embedded systems, the driver should initialize the + display_info.width_mm and display_info.height_mm fields with the + physical size of the display. + +polled + Connector polling mode, a combination of + + DRM_CONNECTOR_POLL_HPD + The connector generates hotplug events and doesn't need to be + periodically polled. The CONNECT and DISCONNECT flags must not + be set together with the HPD flag. + + DRM_CONNECTOR_POLL_CONNECT + Periodically poll the connector for connection. + + DRM_CONNECTOR_POLL_DISCONNECT + Periodically poll the connector for disconnection. + + Set to 0 for connectors that don't support connection status + discovery. + +The connector is then registered with a call to +:c:func:`drm_connector_init()` with a pointer to the connector +functions and a connector type, and exposed through sysfs with a call to +:c:func:`drm_connector_register()`. + +Supported connector types are + +- DRM_MODE_CONNECTOR_VGA +- DRM_MODE_CONNECTOR_DVII +- DRM_MODE_CONNECTOR_DVID +- DRM_MODE_CONNECTOR_DVIA +- DRM_MODE_CONNECTOR_Composite +- DRM_MODE_CONNECTOR_SVIDEO +- DRM_MODE_CONNECTOR_LVDS +- DRM_MODE_CONNECTOR_Component +- DRM_MODE_CONNECTOR_9PinDIN +- DRM_MODE_CONNECTOR_DisplayPort +- DRM_MODE_CONNECTOR_HDMIA +- DRM_MODE_CONNECTOR_HDMIB +- DRM_MODE_CONNECTOR_TV +- DRM_MODE_CONNECTOR_eDP +- DRM_MODE_CONNECTOR_VIRTUAL + +Connectors must be attached to an encoder to be used. For devices that +map connectors to encoders 1:1, the connector should be attached at +initialization time with a call to +:c:func:`drm_mode_connector_attach_encoder()`. The driver must +also set the :c:type:`struct drm_connector ` +encoder field to point to the attached encoder. + +Finally, drivers must initialize the connectors state change detection +with a call to :c:func:`drm_kms_helper_poll_init()`. If at least +one connector is pollable but can't generate hotplug interrupts +(indicated by the DRM_CONNECTOR_POLL_CONNECT and +DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will +automatically be queued to periodically poll for changes. Connectors +that can generate hotplug interrupts must be marked with the +DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must +call :c:func:`drm_helper_hpd_irq_event()`. The function will +queue a delayed work to check the state of all connectors, but no +periodic polling will be done. + +Connector Operations +^^^^^^^^^^^^^^^^^^^^ + + **Note** + + Unless otherwise state, all operations are mandatory. + +DPMS +'''' + +void (\*dpms)(struct drm_connector \*connector, int mode); +The DPMS operation sets the power state of a connector. The mode +argument is one of + +- DRM_MODE_DPMS_ON + +- DRM_MODE_DPMS_STANDBY + +- DRM_MODE_DPMS_SUSPEND + +- DRM_MODE_DPMS_OFF + +In all but DPMS_ON mode the encoder to which the connector is attached +should put the display in low-power mode by driving its signals +appropriately. If more than one connector is attached to the encoder +care should be taken not to change the power state of other displays as +a side effect. Low-power mode should be propagated to the encoders and +CRTCs when all related connectors are put in low-power mode. + +Modes +''''' + +int (\*fill_modes)(struct drm_connector \*connector, uint32_t +max_width, uint32_t max_height); +Fill the mode list with all supported modes for the connector. If the +``max_width`` and ``max_height`` arguments are non-zero, the +implementation must ignore all modes wider than ``max_width`` or higher +than ``max_height``. + +The connector must also fill in this operation its display_info +width_mm and height_mm fields with the connected display physical size +in millimeters. The fields should be set to 0 if the value isn't known +or is not applicable (for instance for projector devices). + +Connection Status +''''''''''''''''' + +The connection status is updated through polling or hotplug events when +supported (see ?). The status value is reported to userspace through +ioctls and must not be used inside the driver, as it only gets +initialized by a call to :c:func:`drm_mode_getconnector()` from +userspace. + +enum drm_connector_status (\*detect)(struct drm_connector +\*connector, bool force); +Check to see if anything is attached to the connector. The ``force`` +parameter is set to false whilst polling or to true when checking the +connector due to user request. ``force`` can be used by the driver to +avoid expensive, destructive operations during automated probing. + +Return connector_status_connected if something is connected to the +connector, connector_status_disconnected if nothing is connected and +connector_status_unknown if the connection state isn't known. + +Drivers should only return connector_status_connected if the +connection status has really been probed as connected. Connectors that +can't detect the connection status, or failed connection status probes, +should return connector_status_unknown. + +Cleanup +~~~~~~~ + +The DRM core manages its objects' lifetime. When an object is not needed +anymore the core calls its destroy function, which must clean up and +free every resource allocated for the object. Every +:c:func:`drm_\*_init()` call must be matched with a corresponding +:c:func:`drm_\*_cleanup()` call to cleanup CRTCs +(:c:func:`drm_crtc_cleanup()`), planes +(:c:func:`drm_plane_cleanup()`), encoders +(:c:func:`drm_encoder_cleanup()`) and connectors +(:c:func:`drm_connector_cleanup()`). Furthermore, connectors that +have been added to sysfs must be removed by a call to +:c:func:`drm_connector_unregister()` before calling +:c:func:`drm_connector_cleanup()`. + +Connectors state change detection must be cleanup up with a call to +:c:func:`drm_kms_helper_poll_fini()`. + +Output discovery and initialization example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + void intel_crt_init(struct drm_device *dev) + { + struct drm_connector *connector; + struct intel_output *intel_output; + + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) + return; + + connector = &intel_output->base; + drm_connector_init(dev, &intel_output->base, + &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); + + drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, + DRM_MODE_ENCODER_DAC); + + drm_mode_connector_attach_encoder(&intel_output->base, + &intel_output->enc); + + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } + + intel_output->type = INTEL_OUTPUT_ANALOG; + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); + drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); + + drm_connector_register(connector); + } + +In the example above (taken from the i915 driver), a CRTC, connector and +encoder combination is created. A device-specific i2c bus is also +created for fetching EDID data and performing monitor detection. Once +the process is complete, the new connector is registered with sysfs to +make its properties available to applications. + +KMS API Functions +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_crtc.c + :export: + +KMS Data Structures +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_crtc.h + :internal: + +KMS Locking +~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c + :doc: kms locking + +.. kernel-doc:: include/drm/drm_modeset_lock.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c + :export: + +Mode Setting Helper Functions +----------------------------- + +The plane, CRTC, encoder and connector functions provided by the drivers +implement the DRM API. They're called by the DRM core and ioctl handlers +to handle device state changes and configuration request. As +implementing those functions often requires logic not specific to +drivers, mid-layer helper functions are available to avoid duplicating +boilerplate code. + +The DRM core contains one mid-layer implementation. The mid-layer +provides implementations of several plane, CRTC, encoder and connector +functions (called from the top of the mid-layer) that pre-process +requests and call lower-level functions provided by the driver (at the +bottom of the mid-layer). For instance, the +:c:func:`drm_crtc_helper_set_config()` function can be used to +fill the :c:type:`struct drm_crtc_funcs ` +set_config field. When called, it will split the set_config operation +in smaller, simpler operations and call the driver to handle them. + +To use the mid-layer, drivers call +:c:func:`drm_crtc_helper_add()`, +:c:func:`drm_encoder_helper_add()` and +:c:func:`drm_connector_helper_add()` functions to install their +mid-layer bottom operations handlers, and fill the :c:type:`struct +drm_crtc_funcs `, :c:type:`struct +drm_encoder_funcs ` and :c:type:`struct +drm_connector_funcs ` structures with +pointers to the mid-layer top API functions. Installing the mid-layer +bottom operation handlers is best done right after registering the +corresponding KMS object. + +The mid-layer is not split between CRTC, encoder and connector +operations. To use it, a driver must provide bottom functions for all of +the three KMS entities. + +Atomic Modeset Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Overview +^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: overview + +Implementing Asynchronous Atomic Commit +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: implementing nonblocking commit + +Atomic State Reset and Initialization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: atomic state reset and initialization + +.. kernel-doc:: include/drm/drm_atomic_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :export: + +Modeset Helper Reference for Common Vtables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h + :internal: + +.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h + :doc: overview + +Legacy CRTC/Modeset Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c + :doc: overview + +Output Probing Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c + :doc: output probing helper overview + +.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c + :export: + +fbdev Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :doc: fbdev helpers + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :export: + +.. kernel-doc:: include/drm/drm_fb_helper.h + :internal: + +Framebuffer CMA Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c + :doc: framebuffer cma helper functions + +.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c + :export: + +Display Port Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c + :doc: dp helpers + +.. kernel-doc:: include/drm/drm_dp_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c + :export: + +Display Port Dual Mode Adaptor Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c + :doc: dp dual mode helpers + +.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c + :export: + +Display Port MST Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c + :doc: dp mst helper + +.. kernel-doc:: include/drm/drm_dp_mst_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c + :export: + +MIPI DSI Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c + :doc: dsi helpers + +.. kernel-doc:: include/drm/drm_mipi_dsi.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c + :export: + +EDID Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_edid.c + :export: + +Rectangle Utilities Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_rect.h + :doc: rect utils + +.. kernel-doc:: include/drm/drm_rect.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_rect.c + :export: + +Flip-work Helper Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_flip_work.h + :doc: flip utils + +.. kernel-doc:: include/drm/drm_flip_work.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_flip_work.c + :export: + +HDMI Infoframes Helper Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Strictly speaking this is not a DRM helper library but generally useable +by any driver interfacing with HDMI outputs like v4l or alsa drivers. +But it nicely fits into the overall topic of mode setting helper +libraries and hence is also included here. + +.. kernel-doc:: include/linux/hdmi.h + :internal: + +.. kernel-doc:: drivers/video/hdmi.c + :export: + +Plane Helper Reference +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c + :doc: overview + +Tile group +~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_crtc.c + :doc: Tile group + +Bridges +~~~~~~~ + +Overview +^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: overview + +Default bridge callback sequence +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: bridge callbacks + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :export: + +Panel Helper Reference +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_panel.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :doc: drm panel + +Simple KMS Helper Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_simple_kms_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :doc: overview + +KMS Properties +-------------- + +Drivers may need to expose additional parameters to applications than +those described in the previous sections. KMS supports attaching +properties to CRTCs, connectors and planes and offers a userspace API to +list, get and set the property values. + +Properties are identified by a name that uniquely defines the property +purpose, and store an associated value. For all property types except +blob properties the value is a 64-bit unsigned integer. + +KMS differentiates between properties and property instances. Drivers +first create properties and then create and associate individual +instances of those properties to objects. A property can be instantiated +multiple times and associated with different objects. Values are stored +in property instances, and all other property information are stored in +the property and shared between all instances of the property. + +Every property is created with a type that influences how the KMS core +handles the property. Supported property types are + +DRM_MODE_PROP_RANGE + Range properties report their minimum and maximum admissible values. + The KMS core verifies that values set by application fit in that + range. + +DRM_MODE_PROP_ENUM + Enumerated properties take a numerical value that ranges from 0 to + the number of enumerated values defined by the property minus one, + and associate a free-formed string name to each value. Applications + can retrieve the list of defined value-name pairs and use the + numerical value to get and set property instance values. + +DRM_MODE_PROP_BITMASK + Bitmask properties are enumeration properties that additionally + restrict all enumerated values to the 0..63 range. Bitmask property + instance values combine one or more of the enumerated bits defined + by the property. + +DRM_MODE_PROP_BLOB + Blob properties store a binary blob without any format restriction. + The binary blobs are created as KMS standalone objects, and blob + property instance values store the ID of their associated blob + object. + + Blob properties are only used for the connector EDID property and + cannot be created by drivers. + +To create a property drivers call one of the following functions +depending on the property type. All property creation functions take +property flags and name, as well as type-specific arguments. + +- struct drm_property \*drm_property_create_range(struct + drm_device \*dev, int flags, const char \*name, uint64_t min, + uint64_t max); + Create a range property with the given minimum and maximum values. + +- struct drm_property \*drm_property_create_enum(struct drm_device + \*dev, int flags, const char \*name, const struct + drm_prop_enum_list \*props, int num_values); + Create an enumerated property. The ``props`` argument points to an + array of ``num_values`` value-name pairs. + +- struct drm_property \*drm_property_create_bitmask(struct + drm_device \*dev, int flags, const char \*name, const struct + drm_prop_enum_list \*props, int num_values); + Create a bitmask property. The ``props`` argument points to an array + of ``num_values`` value-name pairs. + +Properties can additionally be created as immutable, in which case they +will be read-only for applications but can be modified by the driver. To +create an immutable property drivers must set the +DRM_MODE_PROP_IMMUTABLE flag at property creation time. + +When no array of value-name pairs is readily available at property +creation time for enumerated or range properties, drivers can create the +property using the :c:func:`drm_property_create()` function and +manually add enumeration value-name pairs by calling the +:c:func:`drm_property_add_enum()` function. Care must be taken to +properly specify the property type through the ``flags`` argument. + +After creating properties drivers can attach property instances to CRTC, +connector and plane objects by calling the +:c:func:`drm_object_attach_property()`. The function takes a +pointer to the target object, a pointer to the previously created +property and an initial instance value. + +Existing KMS Properties +~~~~~~~~~~~~~~~~~~~~~~~ + +The following table gives description of drm properties exposed by +various modules/drivers. + ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Owner Module/Drivers | Group | Property Name | Type | Property Values | Object attached | Description/Restrictions | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DRM | Generic | “rotation” | BITMASK | { 0, "rotate-0" }, { 1, "rotate-90" }, { 2, "rotate-180" }, { 3, "rotate-270" }, { 4, "reflect-x" }, { 5, "reflect-y" } | CRTC, Plane | rotate-(degrees) rotates the image by the specified amount in degrees in counter clockwise direction. reflect-x and reflect-y reflects the image along the specified axis prior to rotation | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “scaling mode” | ENUM | { "None", "Full", "Center", "Full aspect" } | Connector | Supported by: amdgpu, gma500, i915, nouveau and radeon. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Connector | “EDID” | BLOB \| IMMUTABLE | 0 | Connector | Contains id of edid blob ptr object. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “DPMS” | ENUM | { “On”, “Standby”, “Suspend”, “Off” } | Connector | Contains DPMS operation mode value. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “PATH” | BLOB \| IMMUTABLE | 0 | Connector | Contains topology path to a connector. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “TILE” | BLOB \| IMMUTABLE | 0 | Connector | Contains tiling information for a connector. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Connector | CRTC that connector is attached to (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Plane | “type” | ENUM \| IMMUTABLE | { "Overlay", "Primary", "Cursor" } | Plane | Plane type | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_X” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source x coordinate in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_Y” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source y coordinate in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source width in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source height in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_X” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) x coordinate (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_Y” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) y coordinate (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) width (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) height (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “FB_ID” | OBJECT | DRM_MODE_OBJECT_FB | Plane | Scanout framebuffer (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Plane | CRTC that plane is attached to (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DVI-I | “subconnector” | ENUM | { “Unknown”, “DVI-D”, “DVI-A” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “select subconnector” | ENUM | { “Automatic”, “DVI-D”, “DVI-A” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| TV | “subconnector” | ENUM | { "Unknown", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “select subconnector” | ENUM | { "Automatic", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “left margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “right margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “top margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “bottom margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “brightness” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker reduction” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “overscan” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Virtual GPU | “suggested X” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an X offset for a connector | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “suggested Y” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an Y offset for a connector | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Optional | "aspect ratio" | ENUM | { "None", "4:3", "16:9" } | Connector | TDB | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dirty” | ENUM \| IMMUTABLE | { "Off", "On", "Annotate" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “DEGAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “DEGAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the DEGAMMA_LUT property (the size depends on the underlying hardware). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CTM” | BLOB | 0 | CRTC | DRM property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is an interpreted as a struct drm_color_ctm. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “GAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the gamma lookup table (LUT) mapping pixel data after to the transformation matrix to data sent to the connector. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “GAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the GAMMA_LUT property (the size depends on the underlying hardware). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| i915 | Generic | "Broadcast RGB" | ENUM | { "Automatic", "Full", "Limited 16:235" } | Connector | When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “audio” | ENUM | { "force-dvi", "off", "auto", "on" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| CDV gma-500 | Generic | "Broadcast RGB" | ENUM | { “Full”, “Limited 16:235” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "Broadcast RGB" | ENUM | { “off”, “auto”, “on” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Poulsbo | Generic | “backlight” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| armada | CRTC | "CSC_YUV" | ENUM | { "Auto" , "CCIR601", "CCIR709" } | CRTC | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "CSC_RGB" | ENUM | { "Auto", "Computer system", "Studio" } | CRTC | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Overlay | "colorkey" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_min" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_max" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_val" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_alpha" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_mode" | ENUM | { "disabled", "Y component", "U component" , "V component", "RGB", “R component", "G component", "B component" } | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "brightness" | RANGE | Min=0, Max=256 + 255 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "contrast" | RANGE | Min=0, Max=0x7fff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "saturation" | RANGE | Min=0, Max=0x7fff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| exynos | CRTC | “mode” | ENUM | { "normal", "blank" } | CRTC | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Overlay | “zpos” | RANGE | Min=0, Max=MAX_PLANE-1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| i2c/ch7006_drv | Generic | “scale” | RANGE | Min=0, Max=2 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| TV | “mode” | ENUM | { "PAL", "PAL-M","PAL-N"}, ”PAL-Nc" , "PAL-60", "NTSC-M", "NTSC-J" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| nouveau | NV10 Overlay | "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max=359 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “iturbt_709” | RANGE | Min=0, Max=1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Nv04 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Display | “dithering mode” | ENUM | { "auto", "off", "on" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dithering depth” | ENUM | { "auto", "off", "on", "static 2x2", "dynamic 2x2", "temporal" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “underscan” | ENUM | { "auto", "6 bpc", "8 bpc" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “vibrant hue” | RANGE | Min=0, Max=180 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “color vibrance” | RANGE | Min=0, Max=200 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| omap | Generic | “zorder” | RANGE | Min=0, Max=3 | CRTC, Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| qxl | Generic | “hotplug_mode_update" | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| radeon | DVI-I | “coherent” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DAC enable load detect | “load detection” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| TV Standard | "tv standard" | ENUM | { "ntsc", "pal", "pal-m", "pal-60", "ntsc-j" , "scart-pal", "pal-cn", "secam" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| legacy TMDS PLL detect | "tmds_pll" | ENUM | { "driver", "bios" } | - | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Underscan | "underscan" | ENUM | { "off", "on", "auto" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "underscan hborder" | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "underscan vborder" | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Audio | “audio” | ENUM | { "off", "on", "auto" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| FMT Dithering | “dither” | ENUM | { "off", "on" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| rcar-du | Generic | "alpha" | RANGE | Min=0, Max=255 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "zpos" | RANGE | Min=1, Max=7 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Vertical Blanking +----------------- + +Vertical blanking plays a major role in graphics rendering. To achieve +tear-free display, users must synchronize page flips and/or rendering to +vertical blanking. The DRM API offers ioctls to perform page flips +synchronized to vertical blanking and wait for vertical blanking. + +The DRM core handles most of the vertical blanking management logic, +which involves filtering out spurious interrupts, keeping race-free +blanking counters, coping with counter wrap-around and resets and +keeping use counts. It relies on the driver to generate vertical +blanking interrupts and optionally provide a hardware vertical blanking +counter. Drivers must implement the following operations. + +- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void + (\*disable_vblank) (struct drm_device \*dev, int crtc); + Enable or disable vertical blanking interrupts for the given CRTC. + +- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); + Retrieve the value of the vertical blanking counter for the given + CRTC. If the hardware maintains a vertical blanking counter its value + should be returned. Otherwise drivers can use the + :c:func:`drm_vblank_count()` helper function to handle this + operation. + +Drivers must initialize the vertical blanking handling core with a call +to :c:func:`drm_vblank_init()` in their load operation. + +Vertical blanking interrupts can be enabled by the DRM core or by +drivers themselves (for instance to handle page flipping operations). +The DRM core maintains a vertical blanking use count to ensure that the +interrupts are not disabled while a user still needs them. To increment +the use count, drivers call :c:func:`drm_vblank_get()`. Upon +return vertical blanking interrupts are guaranteed to be enabled. + +To decrement the use count drivers call +:c:func:`drm_vblank_put()`. Only when the use count drops to zero +will the DRM core disable the vertical blanking interrupts after a delay +by scheduling a timer. The delay is accessible through the +vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global +variable and expressed in milliseconds. Its default value is 5000 ms. +Zero means never disable, and a negative value means disable +immediately. Drivers may override the behaviour by setting the +:c:type:`struct drm_device ` +vblank_disable_immediate flag, which when set causes vblank interrupts +to be disabled immediately regardless of the drm_vblank_offdelay +value. The flag should only be set if there's a properly working +hardware vblank counter present. + +When a vertical blanking interrupt occurs drivers only need to call the +:c:func:`drm_handle_vblank()` function to account for the +interrupt. + +Resources allocated by :c:func:`drm_vblank_init()` must be freed +with a call to :c:func:`drm_vblank_cleanup()` in the driver unload +operation handler. + +Vertical Blanking and Interrupt Handling Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_irq.c + :export: + +.. kernel-doc:: include/drm/drmP.h + :functions: drm_crtc_vblank_waitqueue + +Open/Close, File Operations and IOCTLs +-------------------------------------- + +Open and Close +~~~~~~~~~~~~~~ + +int (\*firstopen) (struct drm_device \*); void (\*lastclose) (struct +drm_device \*); int (\*open) (struct drm_device \*, struct drm_file +\*); void (\*preclose) (struct drm_device \*, struct drm_file \*); +void (\*postclose) (struct drm_device \*, struct drm_file \*); + Open and close handlers. None of those methods are mandatory. + +The firstopen method is called by the DRM core for legacy UMS (User Mode +Setting) drivers only when an application opens a device that has no +other opened file handle. UMS drivers can implement it to acquire device +resources. KMS drivers can't use the method and must acquire resources +in the load method instead. + +Similarly the lastclose method is called when the last application +holding a file handle opened on the device closes it, for both UMS and +KMS drivers. Additionally, the method is also called at module unload +time or, for hot-pluggable devices, when the device is unplugged. The +firstopen and lastclose calls can thus be unbalanced. + +The open method is called every time the device is opened by an +application. Drivers can allocate per-file private data in this method +and store them in the struct :c:type:`struct drm_file +` driver_priv field. Note that the open method is +called before firstopen. + +The close operation is split into preclose and postclose methods. +Drivers must stop and cleanup all per-file operations in the preclose +method. For instance pending vertical blanking and page flip events must +be cancelled. No per-file operation is allowed on the file handle after +returning from the preclose method. + +Finally the postclose method is called as the last step of the close +operation, right before calling the lastclose method if no other open +file handle exists for the device. Drivers that have allocated per-file +private data in the open method should free it here. + +The lastclose method should restore CRTC and plane properties to default +value, so that a subsequent open of the device will not inherit state +from the previous user. It can also be used to execute delayed power +switching state changes, e.g. in conjunction with the vga_switcheroo +infrastructure (see ?). Beyond that KMS drivers should not do any +further cleanup. Only legacy UMS drivers might need to clean up device +state so that the vga console or an independent fbdev driver could take +over. + +File Operations +~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_fops.c + :doc: file operations + +.. kernel-doc:: drivers/gpu/drm/drm_fops.c + :export: + +IOCTLs +~~~~~~ + +struct drm_ioctl_desc \*ioctls; int num_ioctls; + Driver-specific ioctls descriptors table. + +Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls +descriptors table is indexed by the ioctl number offset from the base +value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize +the table entries. + +:: + + DRM_IOCTL_DEF_DRV(ioctl, func, flags) + +``ioctl`` is the ioctl name. Drivers must define the DRM_##ioctl and +DRM_IOCTL_##ioctl macros to the ioctl number offset from +DRM_COMMAND_BASE and the ioctl number respectively. The first macro is +private to the device while the second must be exposed to userspace in a +public header. + +``func`` is a pointer to the ioctl handler function compatible with the +``drm_ioctl_t`` type. + +:: + + typedef int drm_ioctl_t(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +``flags`` is a bitmask combination of the following values. It restricts +how the ioctl is allowed to be called. + +- DRM_AUTH - Only authenticated callers allowed + +- DRM_MASTER - The ioctl can only be called on the master file handle + +- DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed + +- DRM_CONTROL_ALLOW - The ioctl can only be called on a control + device + +- DRM_UNLOCKED - The ioctl handler will be called without locking the + DRM global mutex. This is the enforced default for kms drivers (i.e. + using the DRIVER_MODESET flag) and hence shouldn't be used any more + for new drivers. + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :export: + +Legacy Support Code +------------------- + +The section very briefly covers some of the old legacy support code +which is only used by old DRM drivers which have done a so-called +shadow-attach to the underlying device instead of registering as a real +driver. This also includes some of the old generic buffer management and +command submission code. Do not use any of this in new and modern +drivers. + +Legacy Suspend/Resume +~~~~~~~~~~~~~~~~~~~~~ + +The DRM core provides some suspend/resume code, but drivers wanting full +suspend/resume support should provide save() and restore() functions. +These are called at suspend, hibernate, or resume time, and should +perform any state save or restore required by your device across suspend +or hibernate states. + +int (\*suspend) (struct drm_device \*, pm_message_t state); int +(\*resume) (struct drm_device \*); +Those are legacy suspend and resume methods which *only* work with the +legacy shadow-attach driver registration functions. New driver should +use the power management interface provided by their bus type (usually +through the :c:type:`struct device_driver ` +dev_pm_ops) and set these methods to NULL. + +Legacy DMA Services +~~~~~~~~~~~~~~~~~~~ + +This should cover how DMA mapping etc. is supported by the core. These +functions are deprecated and should not be used. + +Userland interfaces +=================== + +The DRM core exports several interfaces to applications, generally +intended to be used through corresponding libdrm wrapper functions. In +addition, drivers export device-specific interfaces for use by userspace +drivers & device-aware applications through ioctls and sysfs files. + +External interfaces include: memory mapping, context management, DMA +operations, AGP management, vblank control, fence management, memory +management, and output management. + +Cover generic ioctls and sysfs layout here. We only need high-level +info, since man pages should cover the rest. + +Render nodes +------------ + +DRM core provides multiple character-devices for user-space to use. +Depending on which device is opened, user-space can perform a different +set of operations (mainly ioctls). The primary node is always created +and called card. Additionally, a currently unused control node, +called controlD is also created. The primary node provides all +legacy operations and historically was the only interface used by +userspace. With KMS, the control node was introduced. However, the +planned KMS control interface has never been written and so the control +node stays unused to date. + +With the increased use of offscreen renderers and GPGPU applications, +clients no longer require running compositors or graphics servers to +make use of a GPU. But the DRM API required unprivileged clients to +authenticate to a DRM-Master prior to getting GPU access. To avoid this +step and to grant clients GPU access without authenticating, render +nodes were introduced. Render nodes solely serve render clients, that +is, no modesetting or privileged ioctls can be issued on render nodes. +Only non-global rendering commands are allowed. If a driver supports +render nodes, it must advertise it via the DRIVER_RENDER DRM driver +capability. If not supported, the primary node must be used for render +clients together with the legacy drmAuth authentication procedure. + +If a driver advertises render node support, DRM core will create a +separate render node called renderD. There will be one render node +per device. No ioctls except PRIME-related ioctls will be allowed on +this node. Especially GEM_OPEN will be explicitly prohibited. Render +nodes are designed to avoid the buffer-leaks, which occur if clients +guess the flink names or mmap offsets on the legacy interface. +Additionally to this basic interface, drivers must mark their +driver-dependent render-only ioctls as DRM_RENDER_ALLOW so render +clients can use them. Driver authors must be careful not to allow any +privileged ioctls on render nodes. + +With render nodes, user-space can now control access to the render node +via basic file-system access-modes. A running graphics server which +authenticates clients on the privileged primary/legacy node is no longer +required. Instead, a client can open the render node and is immediately +granted GPU access. Communication between clients (or servers) is done +via PRIME. FLINK from render node to legacy node is not supported. New +clients must not use the insecure FLINK interface. + +Besides dropping all modeset/global ioctls, render nodes also drop the +DRM-Master concept. There is no reason to associate render clients with +a DRM-Master as they are independent of any graphics server. Besides, +they must work without any running master, anyway. Drivers must be able +to run without a master object if they support render nodes. If, on the +other hand, a driver requires shared state between clients which is +visible to user-space and accessible beyond open-file boundaries, they +cannot support render nodes. + +VBlank event handling +--------------------- + +The DRM core exposes two vertical blank related ioctls: + +DRM_IOCTL_WAIT_VBLANK + This takes a struct drm_wait_vblank structure as its argument, and + it is used to block or request a signal when a specified vblank + event occurs. + +DRM_IOCTL_MODESET_CTL + This was only used for user-mode-settind drivers around modesetting + changes to allow the kernel to update the vblank interrupt after + mode setting, since on many devices the vertical blank counter is + reset to 0 at some point during modeset. Modern drivers should not + call this any more since with kernel mode setting it is a no-op. + +This second part of the GPU Driver Developer's Guide documents driver +code, implementation details and also all the driver-specific userspace +interfaces. Especially since all hardware-acceleration interfaces to +userspace are driver specific for efficiency and other reasons these +interfaces can be rather substantial. Hence every driver has its own +chapter. + +drm/i915 Intel GFX Driver +========================= + +The drm/i915 driver supports all (with the exception of some very early +models) integrated GFX chipsets with both Intel display and rendering +blocks. This excludes a set of SoC platforms with an SGX rendering unit, +those have basic support through the gma500 drm driver. + +Core Driver Infrastructure +-------------------------- + +This section covers core driver infrastructure used by both the display +and the GEM parts of the driver. + +Runtime Power Management +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c + :doc: runtime pm + +.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/intel_uncore.c + :internal: + +Interrupt Handling +~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :doc: interrupt handling + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :functions: intel_irq_init intel_irq_init_hw intel_hpd_init + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :functions: intel_runtime_pm_disable_interrupts + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :functions: intel_runtime_pm_enable_interrupts + +Intel GVT-g Guest Support(vGPU) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c + :doc: Intel GVT-g guest support + +.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c + :internal: + +Display Hardware Handling +------------------------- + +This section covers everything related to the display hardware including +the mode setting infrastructure, plane, sprite and cursor handling and +display, output probing and related topics. + +Mode Setting Infrastructure +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The i915 driver is thus far the only DRM driver which doesn't use the +common DRM helper code to implement mode setting sequences. Thus it has +its own tailor-made infrastructure for executing a display configuration +change. + +Frontbuffer Tracking +~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c + :doc: frontbuffer tracking + +.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem.c + :functions: i915_gem_track_fb + +Display FIFO Underrun Reporting +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c + :doc: fifo underrun handling + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c + :internal: + +Plane Configuration +~~~~~~~~~~~~~~~~~~~ + +This section covers plane configuration and composition with the primary +plane, sprites, cursors and overlays. This includes the infrastructure +to do atomic vsync'ed updates of all this state and also tightly coupled +topics like watermark setup and computation, framebuffer compression and +panel self refresh. + +Atomic Plane Helpers +~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c + :doc: atomic plane helpers + +.. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c + :internal: + +Output Probing +~~~~~~~~~~~~~~ + +This section covers output probing and related infrastructure like the +hotplug interrupt storm detection and mitigation code. Note that the +i915 driver still uses most of the common DRM helper code for output +probing, so those sections fully apply. + +Hotplug +~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c + :doc: Hotplug + +.. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c + :internal: + +High Definition Audio +~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :doc: High Definition Audio over HDMI and Display Port + +.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :internal: + +.. kernel-doc:: include/drm/i915_component.h + :internal: + +Panel Self Refresh PSR (PSR/SRD) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c + :doc: Panel Self Refresh (PSR/SRD) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c + :internal: + +Frame Buffer Compression (FBC) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c + :doc: Frame Buffer Compression (FBC) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c + :internal: + +Display Refresh Rate Switching (DRRS) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :doc: Display Refresh Rate Switching (DRRS) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_dp_set_drrs_state + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_enable + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_disable + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_invalidate + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_flush + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_dp_drrs_init + +DPIO +~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h + :doc: DPIO + +CSR firmware support for DMC +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c + :doc: csr support for dmc + +.. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c + :internal: + +Video BIOS Table (VBT) +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c + :doc: Video BIOS Table (VBT) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/intel_vbt_defs.h + :internal: + +Memory Management and Command Submission +---------------------------------------- + +This sections covers all things related to the GEM implementation in the +i915 driver. + +Batchbuffer Parsing +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c + :doc: batch buffer command parser + +.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c + :internal: + +Batchbuffer Pools +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c + :doc: batch pool + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c + :internal: + +Logical Rings, Logical Ring Contexts and Execlists +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c + :doc: Logical Rings, Logical Ring Contexts and Execlists + +.. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c + :internal: + +Global GTT views +~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c + :doc: Global GTT views + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c + :internal: + +GTT Fences and Swizzling +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c + :internal: + +Global GTT Fence Handling +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c + :doc: fence register handling + +Hardware Tiling and Swizzling Details +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c + :doc: tiling swizzling details + +Object Tiling IOCTLs +~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c + :doc: buffer object tiling + +Buffer Object Eviction +~~~~~~~~~~~~~~~~~~~~~~ + +This section documents the interface functions for evicting buffer +objects to make space available in the virtual gpu address spaces. Note +that this is mostly orthogonal to shrinking buffer objects caches, which +has the goal to make main memory (shared with the gpu through the +unified memory architecture) available. + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_evict.c + :internal: + +Buffer Object Memory Shrinking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section documents the interface function for shrinking memory usage +of buffer object caches. Shrinking is used to make main memory +available. Note that this is mostly orthogonal to evicting buffer +objects, which has the goal to make space in gpu virtual address spaces. + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_shrinker.c + :internal: + +GuC +--- + +GuC-specific firmware loader +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c + :doc: GuC-specific firmware loader + +.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c + :internal: + +GuC-based command submission +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c + :doc: GuC-based command submission + +.. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c + :internal: + +GuC Firmware Layout +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fwif.h + :doc: GuC Firmware Layout + +Tracing +------- + +This sections covers all things related to the tracepoints implemented +in the i915 driver. + +i915_ppgtt_create and i915_ppgtt_release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h + :doc: i915_ppgtt_create and i915_ppgtt_release tracepoints + +i915_context_create and i915_context_free +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h + :doc: i915_context_create and i915_context_free tracepoints + +switch_mm +~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h + :doc: switch_mm tracepoint + +.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/drm/i915/i915_irq.c + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :doc: Overview + +Modes of Use +============ + +Manual switching and manual power control +----------------------------------------- + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :doc: Manual switching and manual power control + +Driver power control +-------------------- + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :doc: Driver power control + +API +=== + +Public functions +---------------- + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :export: + +Public structures +----------------- + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_handler + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_client_ops + +Public constants +---------------- + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_handler_flags_t + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_client_id + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_state + +Private structures +------------------ + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :functions: vgasr_priv + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :functions: vga_switcheroo_client + +Handlers +======== + +apple-gmux Handler +------------------ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Overview + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Interrupt + +Graphics mux +~~~~~~~~~~~~ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Graphics mux + +Power control +~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Power control + +Backlight control +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Backlight control + +Public functions +~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/linux/apple-gmux.h + :internal: + +.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/vga/vga_switcheroo.c + +.. WARNING: DOCPROC directive not supported: !Cinclude/linux/vga_switcheroo.h + +.. WARNING: DOCPROC directive not supported: !Cdrivers/platform/x86/apple-gmux.c diff --git a/Documentation/index.rst b/Documentation/index.rst index 71a276f34c7f..dacc77b43c29 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -13,6 +13,7 @@ Contents: .. toctree:: :maxdepth: 2 + gpu/index Indices and tables ================== -- cgit v1.3-14-g43fede From ca00c2b986eaf696265fbdc7643e66796e55cb2a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Jun 2016 14:48:58 +0300 Subject: Documentation/gpu: split up the gpu documentation Make the gpu documentation easier to manage by splitting to separate files. Again, this is just the split, no real edits. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/bd2b599b5105c28c8f05923005e6cc9b7efa7fc1.1466506505.git.jani.nikula@intel.com --- Documentation/gpu/drm-internals.rst | 1998 ++++++++++++++++++++++++++ Documentation/gpu/drm-uapi.rst | 91 ++ Documentation/gpu/i915.rst | 346 +++++ Documentation/gpu/index.rst | 2602 +--------------------------------- Documentation/gpu/introduction.rst | 50 + Documentation/gpu/vga-switcheroo.rst | 102 ++ 6 files changed, 2593 insertions(+), 2596 deletions(-) create mode 100644 Documentation/gpu/drm-internals.rst create mode 100644 Documentation/gpu/drm-uapi.rst create mode 100644 Documentation/gpu/i915.rst create mode 100644 Documentation/gpu/introduction.rst create mode 100644 Documentation/gpu/vga-switcheroo.rst (limited to 'Documentation') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst new file mode 100644 index 000000000000..8b8257891396 --- /dev/null +++ b/Documentation/gpu/drm-internals.rst @@ -0,0 +1,1998 @@ +DRM Internals +============= + +This chapter documents DRM internals relevant to driver authors and +developers working to add support for the latest features to existing +drivers. + +First, we go over some typical driver initialization requirements, like +setting up command buffers, creating an initial output configuration, +and initializing core services. Subsequent sections cover core internals +in more detail, providing implementation notes and examples. + +The DRM layer provides several services to graphics drivers, many of +them driven by the application interfaces it provides through libdrm, +the library that wraps most of the DRM ioctls. These include vblank +event handling, memory management, output management, framebuffer +management, command submission & fencing, suspend/resume support, and +DMA services. + +Driver Initialization +--------------------- + +At the core of every DRM driver is a :c:type:`struct drm_driver +` structure. Drivers typically statically initialize +a drm_driver structure, and then pass it to +:c:func:`drm_dev_alloc()` to allocate a device instance. After the +device instance is fully initialized it can be registered (which makes +it accessible from userspace) using :c:func:`drm_dev_register()`. + +The :c:type:`struct drm_driver ` structure +contains static information that describes the driver and features it +supports, and pointers to methods that the DRM core will call to +implement the DRM API. We will first go through the :c:type:`struct +drm_driver ` static information fields, and will +then describe individual operations in details as they get used in later +sections. + +Driver Information +~~~~~~~~~~~~~~~~~~ + +Driver Features +^^^^^^^^^^^^^^^ + +Drivers inform the DRM core about their requirements and supported +features by setting appropriate flags in the driver_features field. +Since those flags influence the DRM core behaviour since registration +time, most of them must be set to registering the :c:type:`struct +drm_driver ` instance. + +u32 driver_features; + +DRIVER_USE_AGP + Driver uses AGP interface, the DRM core will manage AGP resources. + +DRIVER_REQUIRE_AGP + Driver needs AGP interface to function. AGP initialization failure + will become a fatal error. + +DRIVER_PCI_DMA + Driver is capable of PCI DMA, mapping of PCI DMA buffers to + userspace will be enabled. Deprecated. + +DRIVER_SG + Driver can perform scatter/gather DMA, allocation and mapping of + scatter/gather buffers will be enabled. Deprecated. + +DRIVER_HAVE_DMA + Driver supports DMA, the userspace DMA API will be supported. + Deprecated. + +DRIVER_HAVE_IRQ; DRIVER_IRQ_SHARED + DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler + managed by the DRM Core. The core will support simple IRQ handler + installation when the flag is set. The installation process is + described in ?. + + DRIVER_IRQ_SHARED indicates whether the device & handler support + shared IRQs (note that this is required of PCI drivers). + +DRIVER_GEM + Driver use the GEM memory manager. + +DRIVER_MODESET + Driver supports mode setting interfaces (KMS). + +DRIVER_PRIME + Driver implements DRM PRIME buffer sharing. + +DRIVER_RENDER + Driver supports dedicated render nodes. + +DRIVER_ATOMIC + Driver supports atomic properties. In this case the driver must + implement appropriate obj->atomic_get_property() vfuncs for any + modeset objects with driver specific properties. + +Major, Minor and Patchlevel +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +int major; int minor; int patchlevel; +The DRM core identifies driver versions by a major, minor and patch +level triplet. The information is printed to the kernel log at +initialization time and passed to userspace through the +DRM_IOCTL_VERSION ioctl. + +The major and minor numbers are also used to verify the requested driver +API version passed to DRM_IOCTL_SET_VERSION. When the driver API +changes between minor versions, applications can call +DRM_IOCTL_SET_VERSION to select a specific version of the API. If the +requested major isn't equal to the driver major, or the requested minor +is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will +return an error. Otherwise the driver's set_version() method will be +called with the requested version. + +Name, Description and Date +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +char \*name; char \*desc; char \*date; +The driver name is printed to the kernel log at initialization time, +used for IRQ registration and passed to userspace through +DRM_IOCTL_VERSION. + +The driver description is a purely informative string passed to +userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by +the kernel. + +The driver date, formatted as YYYYMMDD, is meant to identify the date of +the latest modification to the driver. However, as most drivers fail to +update it, its value is mostly useless. The DRM core prints it to the +kernel log at initialization time and passes it to userspace through the +DRM_IOCTL_VERSION ioctl. + +Device Instance and Driver Handling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_drv.c + :doc: driver instance overview + +.. kernel-doc:: drivers/gpu/drm/drm_drv.c + :export: + +Driver Load +~~~~~~~~~~~ + +IRQ Registration +^^^^^^^^^^^^^^^^ + +The DRM core tries to facilitate IRQ handler registration and +unregistration by providing :c:func:`drm_irq_install()` and +:c:func:`drm_irq_uninstall()` functions. Those functions only +support a single interrupt per device, devices that use more than one +IRQs need to be handled manually. + +Managed IRQ Registration +'''''''''''''''''''''''' + +:c:func:`drm_irq_install()` starts by calling the irq_preinstall +driver operation. The operation is optional and must make sure that the +interrupt will not get fired by clearing all pending interrupt flags or +disabling the interrupt. + +The passed-in IRQ will then be requested by a call to +:c:func:`request_irq()`. If the DRIVER_IRQ_SHARED driver feature +flag is set, a shared (IRQF_SHARED) IRQ handler will be requested. + +The IRQ handler function must be provided as the mandatory irq_handler +driver operation. It will get passed directly to +:c:func:`request_irq()` and thus has the same prototype as all IRQ +handlers. It will get called with a pointer to the DRM device as the +second argument. + +Finally the function calls the optional irq_postinstall driver +operation. The operation usually enables interrupts (excluding the +vblank interrupt, which is enabled separately), but drivers may choose +to enable/disable interrupts at a different time. + +:c:func:`drm_irq_uninstall()` is similarly used to uninstall an +IRQ handler. It starts by waking up all processes waiting on a vblank +interrupt to make sure they don't hang, and then calls the optional +irq_uninstall driver operation. The operation must disable all hardware +interrupts. Finally the function frees the IRQ by calling +:c:func:`free_irq()`. + +Manual IRQ Registration +''''''''''''''''''''''' + +Drivers that require multiple interrupt handlers can't use the managed +IRQ registration functions. In that case IRQs must be registered and +unregistered manually (usually with the :c:func:`request_irq()` and +:c:func:`free_irq()` functions, or their devm_\* equivalent). + +When manually registering IRQs, drivers must not set the +DRIVER_HAVE_IRQ driver feature flag, and must not provide the +irq_handler driver operation. They must set the :c:type:`struct +drm_device ` irq_enabled field to 1 upon +registration of the IRQs, and clear it to 0 after unregistering the +IRQs. + +Memory Manager Initialization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Every DRM driver requires a memory manager which must be initialized at +load time. DRM currently contains two memory managers, the Translation +Table Manager (TTM) and the Graphics Execution Manager (GEM). This +document describes the use of the GEM memory manager only. See ? for +details. + +Miscellaneous Device Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Another task that may be necessary for PCI devices during configuration +is mapping the video BIOS. On many devices, the VBIOS describes device +configuration, LCD panel timings (if any), and contains flags indicating +device state. Mapping the BIOS can be done using the pci_map_rom() +call, a convenience function that takes care of mapping the actual ROM, +whether it has been shadowed into memory (typically at address 0xc0000) +or exists on the PCI device in the ROM BAR. Note that after the ROM has +been mapped and any necessary information has been extracted, it should +be unmapped; on many devices, the ROM address decoder is shared with +other BARs, so leaving it mapped could cause undesired behaviour like +hangs or memory corruption. + +Bus-specific Device Registration and PCI Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A number of functions are provided to help with device registration. The +functions deal with PCI and platform devices respectively and are only +provided for historical reasons. These are all deprecated and shouldn't +be used in new drivers. Besides that there's a few helpers for pci +drivers. + +.. kernel-doc:: drivers/gpu/drm/drm_pci.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_platform.c + :export: + +Memory management +----------------- + +Modern Linux systems require large amount of graphics memory to store +frame buffers, textures, vertices and other graphics-related data. Given +the very dynamic nature of many of that data, managing graphics memory +efficiently is thus crucial for the graphics stack and plays a central +role in the DRM infrastructure. + +The DRM core includes two memory managers, namely Translation Table Maps +(TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory +manager to be developed and tried to be a one-size-fits-them all +solution. It provides a single userspace API to accommodate the need of +all hardware, supporting both Unified Memory Architecture (UMA) devices +and devices with dedicated video RAM (i.e. most discrete video cards). +This resulted in a large, complex piece of code that turned out to be +hard to use for driver development. + +GEM started as an Intel-sponsored project in reaction to TTM's +complexity. Its design philosophy is completely different: instead of +providing a solution to every graphics memory-related problems, GEM +identified common code between drivers and created a support library to +share it. GEM has simpler initialization and execution requirements than +TTM, but has no video RAM management capabilities and is thus limited to +UMA devices. + +The Translation Table Manager (TTM) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +TTM design background and information belongs here. + +TTM initialization +^^^^^^^^^^^^^^^^^^ + + **Warning** + + This section is outdated. + +Drivers wishing to support TTM must fill out a drm_bo_driver +structure. The structure contains several fields with function pointers +for initializing the TTM, allocating and freeing memory, waiting for +command completion and fence synchronization, and memory migration. See +the radeon_ttm.c file for an example of usage. + +The ttm_global_reference structure is made up of several fields: + +:: + + struct ttm_global_reference { + enum ttm_global_types global_type; + size_t size; + void *object; + int (*init) (struct ttm_global_reference *); + void (*release) (struct ttm_global_reference *); + }; + + +There should be one global reference structure for your memory manager +as a whole, and there will be others for each object created by the +memory manager at runtime. Your global TTM should have a type of +TTM_GLOBAL_TTM_MEM. The size field for the global object should be +sizeof(struct ttm_mem_global), and the init and release hooks should +point at your driver-specific init and release routines, which probably +eventually call ttm_mem_global_init and ttm_mem_global_release, +respectively. + +Once your global TTM accounting structure is set up and initialized by +calling ttm_global_item_ref() on it, you need to create a buffer +object TTM to provide a pool for buffer object allocation by clients and +the kernel itself. The type of this object should be +TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct +ttm_bo_global). Again, driver-specific init and release functions may +be provided, likely eventually calling ttm_bo_global_init() and +ttm_bo_global_release(), respectively. Also, like the previous +object, ttm_global_item_ref() is used to create an initial reference +count for the TTM, which will call your initialization function. + +The Graphics Execution Manager (GEM) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The GEM design approach has resulted in a memory manager that doesn't +provide full coverage of all (or even all common) use cases in its +userspace or kernel API. GEM exposes a set of standard memory-related +operations to userspace and a set of helper functions to drivers, and +let drivers implement hardware-specific operations with their own +private API. + +The GEM userspace API is described in the `GEM - the Graphics Execution +Manager `__ article on LWN. While +slightly outdated, the document provides a good overview of the GEM API +principles. Buffer allocation and read and write operations, described +as part of the common GEM API, are currently implemented using +driver-specific ioctls. + +GEM is data-agnostic. It manages abstract buffer objects without knowing +what individual buffers contain. APIs that require knowledge of buffer +contents or purpose, such as buffer allocation or synchronization +primitives, are thus outside of the scope of GEM and must be implemented +using driver-specific ioctls. + +On a fundamental level, GEM involves several operations: + +- Memory allocation and freeing +- Command execution +- Aperture management at command execution time + +Buffer object allocation is relatively straightforward and largely +provided by Linux's shmem layer, which provides memory to back each +object. + +Device-specific operations, such as command execution, pinning, buffer +read & write, mapping, and domain ownership transfers are left to +driver-specific ioctls. + +GEM Initialization +^^^^^^^^^^^^^^^^^^ + +Drivers that use GEM must set the DRIVER_GEM bit in the struct +:c:type:`struct drm_driver ` driver_features +field. The DRM core will then automatically initialize the GEM core +before calling the load operation. Behind the scene, this will create a +DRM Memory Manager object which provides an address space pool for +object allocation. + +In a KMS configuration, drivers need to allocate and initialize a +command ring buffer following core GEM initialization if required by the +hardware. UMA devices usually have what is called a "stolen" memory +region, which provides space for the initial framebuffer and large, +contiguous memory regions required by the device. This space is +typically not managed by GEM, and must be initialized separately into +its own DRM MM object. + +GEM Objects Creation +^^^^^^^^^^^^^^^^^^^^ + +GEM splits creation of GEM objects and allocation of the memory that +backs them in two distinct operations. + +GEM objects are represented by an instance of struct :c:type:`struct +drm_gem_object `. Drivers usually need to +extend GEM objects with private information and thus create a +driver-specific GEM object structure type that embeds an instance of +struct :c:type:`struct drm_gem_object `. + +To create a GEM object, a driver allocates memory for an instance of its +specific GEM object type and initializes the embedded struct +:c:type:`struct drm_gem_object ` with a call +to :c:func:`drm_gem_object_init()`. The function takes a pointer +to the DRM device, a pointer to the GEM object and the buffer object +size in bytes. + +GEM uses shmem to allocate anonymous pageable memory. +:c:func:`drm_gem_object_init()` will create an shmfs file of the +requested size and store it into the struct :c:type:`struct +drm_gem_object ` filp field. The memory is +used as either main storage for the object when the graphics hardware +uses system memory directly or as a backing store otherwise. + +Drivers are responsible for the actual physical pages allocation by +calling :c:func:`shmem_read_mapping_page_gfp()` for each page. +Note that they can decide to allocate pages when initializing the GEM +object, or to delay allocation until the memory is needed (for instance +when a page fault occurs as a result of a userspace memory access or +when the driver needs to start a DMA transfer involving the memory). + +Anonymous pageable memory allocation is not always desired, for instance +when the hardware requires physically contiguous system memory as is +often the case in embedded devices. Drivers can create GEM objects with +no shmfs backing (called private GEM objects) by initializing them with +a call to :c:func:`drm_gem_private_object_init()` instead of +:c:func:`drm_gem_object_init()`. Storage for private GEM objects +must be managed by drivers. + +GEM Objects Lifetime +^^^^^^^^^^^^^^^^^^^^ + +All GEM objects are reference-counted by the GEM core. References can be +acquired and release by :c:func:`calling +drm_gem_object_reference()` and +:c:func:`drm_gem_object_unreference()` respectively. The caller +must hold the :c:type:`struct drm_device ` +struct_mutex lock when calling +:c:func:`drm_gem_object_reference()`. As a convenience, GEM +provides :c:func:`drm_gem_object_unreference_unlocked()` +functions that can be called without holding the lock. + +When the last reference to a GEM object is released the GEM core calls +the :c:type:`struct drm_driver ` gem_free_object +operation. That operation is mandatory for GEM-enabled drivers and must +free the GEM object and all associated resources. + +void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are +responsible for freeing all GEM object resources. This includes the +resources created by the GEM core, which need to be released with +:c:func:`drm_gem_object_release()`. + +GEM Objects Naming +^^^^^^^^^^^^^^^^^^ + +Communication between userspace and the kernel refers to GEM objects +using local handles, global names or, more recently, file descriptors. +All of those are 32-bit integer values; the usual Linux kernel limits +apply to the file descriptors. + +GEM handles are local to a DRM file. Applications get a handle to a GEM +object through a driver-specific ioctl, and can use that handle to refer +to the GEM object in other standard or driver-specific ioctls. Closing a +DRM file handle frees all its GEM handles and dereferences the +associated GEM objects. + +To create a handle for a GEM object drivers call +:c:func:`drm_gem_handle_create()`. The function takes a pointer +to the DRM file and the GEM object and returns a locally unique handle. +When the handle is no longer needed drivers delete it with a call to +:c:func:`drm_gem_handle_delete()`. Finally the GEM object +associated with a handle can be retrieved by a call to +:c:func:`drm_gem_object_lookup()`. + +Handles don't take ownership of GEM objects, they only take a reference +to the object that will be dropped when the handle is destroyed. To +avoid leaking GEM objects, drivers must make sure they drop the +reference(s) they own (such as the initial reference taken at object +creation time) as appropriate, without any special consideration for the +handle. For example, in the particular case of combined GEM object and +handle creation in the implementation of the dumb_create operation, +drivers must drop the initial reference to the GEM object before +returning the handle. + +GEM names are similar in purpose to handles but are not local to DRM +files. They can be passed between processes to reference a GEM object +globally. Names can't be used directly to refer to objects in the DRM +API, applications must convert handles to names and names to handles +using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls +respectively. The conversion is handled by the DRM core without any +driver-specific support. + +GEM also supports buffer sharing with dma-buf file descriptors through +PRIME. GEM-based drivers must use the provided helpers functions to +implement the exporting and importing correctly. See ?. Since sharing +file descriptors is inherently more secure than the easily guessable and +global GEM names it is the preferred buffer sharing mechanism. Sharing +buffers through GEM names is only supported for legacy userspace. +Furthermore PRIME also allows cross-device buffer sharing since it is +based on dma-bufs. + +GEM Objects Mapping +^^^^^^^^^^^^^^^^^^^ + +Because mapping operations are fairly heavyweight GEM favours +read/write-like access to buffers, implemented through driver-specific +ioctls, over mapping buffers to userspace. However, when random access +to the buffer is needed (to perform software rendering for instance), +direct access to the object can be more efficient. + +The mmap system call can't be used directly to map GEM objects, as they +don't have their own file handle. Two alternative methods currently +co-exist to map GEM objects to userspace. The first method uses a +driver-specific ioctl to perform the mapping operation, calling +:c:func:`do_mmap()` under the hood. This is often considered +dubious, seems to be discouraged for new GEM-enabled drivers, and will +thus not be described here. + +The second method uses the mmap system call on the DRM file handle. void +\*mmap(void \*addr, size_t length, int prot, int flags, int fd, off_t +offset); DRM identifies the GEM object to be mapped by a fake offset +passed through the mmap offset argument. Prior to being mapped, a GEM +object must thus be associated with a fake offset. To do so, drivers +must call :c:func:`drm_gem_create_mmap_offset()` on the object. + +Once allocated, the fake offset value must be passed to the application +in a driver-specific way and can then be used as the mmap offset +argument. + +The GEM core provides a helper method :c:func:`drm_gem_mmap()` to +handle object mapping. The method can be set directly as the mmap file +operation handler. It will look up the GEM object based on the offset +value and set the VMA operations to the :c:type:`struct drm_driver +` gem_vm_ops field. Note that +:c:func:`drm_gem_mmap()` doesn't map memory to userspace, but +relies on the driver-provided fault handler to map pages individually. + +To use :c:func:`drm_gem_mmap()`, drivers must fill the struct +:c:type:`struct drm_driver ` gem_vm_ops field +with a pointer to VM operations. + +struct vm_operations_struct \*gem_vm_ops struct +vm_operations_struct { void (\*open)(struct vm_area_struct \* area); +void (\*close)(struct vm_area_struct \* area); int (\*fault)(struct +vm_area_struct \*vma, struct vm_fault \*vmf); }; + +The open and close operations must update the GEM object reference +count. Drivers can use the :c:func:`drm_gem_vm_open()` and +:c:func:`drm_gem_vm_close()` helper functions directly as open +and close handlers. + +The fault operation handler is responsible for mapping individual pages +to userspace when a page fault occurs. Depending on the memory +allocation scheme, drivers can allocate pages at fault time, or can +decide to allocate memory for the GEM object at the time the object is +created. + +Drivers that want to map the GEM object upfront instead of handling page +faults can implement their own mmap file operation handler. + +Memory Coherency +^^^^^^^^^^^^^^^^ + +When mapped to the device or used in a command buffer, backing pages for +an object are flushed to memory and marked write combined so as to be +coherent with the GPU. Likewise, if the CPU accesses an object after the +GPU has finished rendering to the object, then the object must be made +coherent with the CPU's view of memory, usually involving GPU cache +flushing of various kinds. This core CPU<->GPU coherency management is +provided by a device-specific ioctl, which evaluates an object's current +domain and performs any necessary flushing or synchronization to put the +object into the desired coherency domain (note that the object may be +busy, i.e. an active render target; in that case, setting the domain +blocks the client and waits for rendering to complete before performing +any necessary flushing operations). + +Command Execution +^^^^^^^^^^^^^^^^^ + +Perhaps the most important GEM function for GPU devices is providing a +command execution interface to clients. Client programs construct +command buffers containing references to previously allocated memory +objects, and then submit them to GEM. At that point, GEM takes care to +bind all the objects into the GTT, execute the buffer, and provide +necessary synchronization between clients accessing the same buffers. +This often involves evicting some objects from the GTT and re-binding +others (a fairly expensive operation), and providing relocation support +which hides fixed GTT offsets from clients. Clients must take care not +to submit command buffers that reference more objects than can fit in +the GTT; otherwise, GEM will reject them and no rendering will occur. +Similarly, if several objects in the buffer require fence registers to +be allocated for correct rendering (e.g. 2D blits on pre-965 chips), +care must be taken not to require more fence registers than are +available to the client. Such resource management should be abstracted +from the client in libdrm. + +GEM Function Reference +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_gem.c + :export: + +.. kernel-doc:: include/drm/drm_gem.h + :internal: + +VMA Offset Manager +~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :doc: vma offset manager + +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :export: + +.. kernel-doc:: include/drm/drm_vma_manager.h + :internal: + +PRIME Buffer Sharing +~~~~~~~~~~~~~~~~~~~~ + +PRIME is the cross device buffer sharing framework in drm, originally +created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME +buffers are dma-buf based file descriptors. + +Overview and Driver Interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Similar to GEM global names, PRIME file descriptors are also used to +share buffer objects across processes. They offer additional security: +as file descriptors must be explicitly sent over UNIX domain sockets to +be shared between applications, they can't be guessed like the globally +unique GEM names. + +Drivers that support the PRIME API must set the DRIVER_PRIME bit in the +struct :c:type:`struct drm_driver ` +driver_features field, and implement the prime_handle_to_fd and +prime_fd_to_handle operations. + +int (\*prime_handle_to_fd)(struct drm_device \*dev, struct drm_file +\*file_priv, uint32_t handle, uint32_t flags, int \*prime_fd); int +(\*prime_fd_to_handle)(struct drm_device \*dev, struct drm_file +\*file_priv, int prime_fd, uint32_t \*handle); Those two operations +convert a handle to a PRIME file descriptor and vice versa. Drivers must +use the kernel dma-buf buffer sharing framework to manage the PRIME file +descriptors. Similar to the mode setting API PRIME is agnostic to the +underlying buffer object manager, as long as handles are 32bit unsigned +integers. + +While non-GEM drivers must implement the operations themselves, GEM +drivers must use the :c:func:`drm_gem_prime_handle_to_fd()` and +:c:func:`drm_gem_prime_fd_to_handle()` helper functions. Those +helpers rely on the driver gem_prime_export and gem_prime_import +operations to create a dma-buf instance from a GEM object (dma-buf +exporter role) and to create a GEM object from a dma-buf instance +(dma-buf importer role). + +struct dma_buf \* (\*gem_prime_export)(struct drm_device \*dev, +struct drm_gem_object \*obj, int flags); struct drm_gem_object \* +(\*gem_prime_import)(struct drm_device \*dev, struct dma_buf +\*dma_buf); These two operations are mandatory for GEM drivers that +support PRIME. + +PRIME Helper Functions +^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_prime.c + :doc: PRIME Helpers + +PRIME Function References +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_prime.c + :export: + +DRM MM Range Allocator +~~~~~~~~~~~~~~~~~~~~~~ + +Overview +^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :doc: Overview + +LRU Scan/Eviction Support +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :doc: lru scan roaster + +DRM MM Range Allocator Function References +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :export: + +.. kernel-doc:: include/drm/drm_mm.h + :internal: + +CMA Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :doc: cma helpers + +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :export: + +.. kernel-doc:: include/drm/drm_gem_cma_helper.h + :internal: + +Mode Setting +------------ + +Drivers must initialize the mode setting core by calling +:c:func:`drm_mode_config_init()` on the DRM device. The function +initializes the :c:type:`struct drm_device ` +mode_config field and never fails. Once done, mode configuration must +be setup by initializing the following fields. + +- int min_width, min_height; int max_width, max_height; + Minimum and maximum width and height of the frame buffers in pixel + units. + +- struct drm_mode_config_funcs \*funcs; + Mode setting functions. + +Display Modes Function Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_modes.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_modes.c + :export: + +Atomic Mode Setting Function Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :internal: + +Frame Buffer Abstraction +~~~~~~~~~~~~~~~~~~~~~~~~ + +Frame buffers are abstract memory objects that provide a source of +pixels to scanout to a CRTC. Applications explicitly request the +creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls +and receive an opaque handle that can be passed to the KMS CRTC control, +plane configuration and page flip functions. + +Frame buffers rely on the underneath memory manager for low-level memory +operations. When creating a frame buffer applications pass a memory +handle (or a list of memory handles for multi-planar formats) through +the ``drm_mode_fb_cmd2`` argument. For drivers using GEM as their +userspace buffer management interface this would be a GEM handle. +Drivers are however free to use their own backing storage object +handles, e.g. vmwgfx directly exposes special TTM handles to userspace +and so expects TTM handles in the create ioctl and not GEM handles. + +The lifetime of a drm framebuffer is controlled with a reference count, +drivers can grab additional references with +:c:func:`drm_framebuffer_reference()`and drop them again with +:c:func:`drm_framebuffer_unreference()`. For driver-private +framebuffers for which the last reference is never dropped (e.g. for the +fbdev framebuffer when the struct :c:type:`struct drm_framebuffer +` is embedded into the fbdev helper struct) +drivers can manually clean up a framebuffer at module unload time with +:c:func:`drm_framebuffer_unregister_private()`. + +DRM Format Handling +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_fourcc.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c + :export: + +Dumb Buffer Objects +~~~~~~~~~~~~~~~~~~~ + +The KMS API doesn't standardize backing storage object creation and +leaves it to driver-specific ioctls. Furthermore actually creating a +buffer object even for GEM-based drivers is done through a +driver-specific ioctl - GEM only has a common userspace interface for +sharing and destroying objects. While not an issue for full-fledged +graphics stacks that include device-specific userspace components (in +libdrm for instance), this limit makes DRM-based early boot graphics +unnecessarily complex. + +Dumb objects partly alleviate the problem by providing a standard API to +create dumb buffers suitable for scanout, which can then be used to +create KMS frame buffers. + +To support dumb objects drivers must implement the dumb_create, +dumb_destroy and dumb_map_offset operations. + +- int (\*dumb_create)(struct drm_file \*file_priv, struct + drm_device \*dev, struct drm_mode_create_dumb \*args); + The dumb_create operation creates a driver object (GEM or TTM + handle) suitable for scanout based on the width, height and depth + from the struct :c:type:`struct drm_mode_create_dumb + ` argument. It fills the argument's + handle, pitch and size fields with a handle for the newly created + object and its line pitch and size in bytes. + +- int (\*dumb_destroy)(struct drm_file \*file_priv, struct + drm_device \*dev, uint32_t handle); + The dumb_destroy operation destroys a dumb object created by + dumb_create. + +- int (\*dumb_map_offset)(struct drm_file \*file_priv, struct + drm_device \*dev, uint32_t handle, uint64_t \*offset); + The dumb_map_offset operation associates an mmap fake offset with + the object given by the handle and returns it. Drivers must use the + :c:func:`drm_gem_create_mmap_offset()` function to associate + the fake offset as described in ?. + +Note that dumb objects may not be used for gpu acceleration, as has been +attempted on some ARM embedded platforms. Such drivers really must have +a hardware-specific ioctl to allocate suitable buffer objects. + +Output Polling +~~~~~~~~~~~~~~ + +void (\*output_poll_changed)(struct drm_device \*dev); +This operation notifies the driver that the status of one or more +connectors has changed. Drivers that use the fb helper can just call the +:c:func:`drm_fb_helper_hotplug_event()` function to handle this +operation. + +KMS Initialization and Cleanup +------------------------------ + +A KMS device is abstracted and exposed as a set of planes, CRTCs, +encoders and connectors. KMS drivers must thus create and initialize all +those objects at load time after initializing mode setting. + +CRTCs (:c:type:`struct drm_crtc `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A CRTC is an abstraction representing a part of the chip that contains a +pointer to a scanout buffer. Therefore, the number of CRTCs available +determines how many independent scanout buffers can be active at any +given time. The CRTC structure contains several fields to support this: +a pointer to some video memory (abstracted as a frame buffer object), a +display mode, and an (x, y) offset into the video memory to support +panning or configurations where one piece of video memory spans multiple +CRTCs. + +CRTC Initialization +^^^^^^^^^^^^^^^^^^^ + +A KMS device must create and register at least one struct +:c:type:`struct drm_crtc ` instance. The instance is +allocated and zeroed by the driver, possibly as part of a larger +structure, and registered with a call to :c:func:`drm_crtc_init()` +with a pointer to CRTC functions. + +Planes (:c:type:`struct drm_plane `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A plane represents an image source that can be blended with or overlayed +on top of a CRTC during the scanout process. Planes are associated with +a frame buffer to crop a portion of the image memory (source) and +optionally scale it to a destination size. The result is then blended +with or overlayed on top of a CRTC. + +The DRM core recognizes three types of planes: + +- DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. + Primary planes are the planes operated upon by CRTC modesetting and + flipping operations described in the page_flip hook in + :c:type:`struct drm_crtc_funcs `. +- DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. + Cursor planes are the planes operated upon by the + DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls. +- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor + planes. Some drivers refer to these types of planes as "sprites" + internally. + +For compatibility with legacy userspace, only overlay planes are made +available to userspace by default. Userspace clients may set the +DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate +that they wish to receive a universal plane list containing all plane +types. + +Plane Initialization +^^^^^^^^^^^^^^^^^^^^ + +To create a plane, a KMS drivers allocates and zeroes an instances of +:c:type:`struct drm_plane ` (possibly as part of a +larger structure) and registers it with a call to +:c:func:`drm_universal_plane_init()`. The function takes a +bitmask of the CRTCs that can be associated with the plane, a pointer to +the plane functions, a list of format supported formats, and the type of +plane (primary, cursor, or overlay) being initialized. + +Cursor and overlay planes are optional. All drivers should provide one +primary plane per CRTC (although this requirement may change in the +future); drivers that do not wish to provide special handling for +primary planes may make use of the helper functions described in ? to +create and register a primary plane with standard capabilities. + +Encoders (:c:type:`struct drm_encoder `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An encoder takes pixel data from a CRTC and converts it to a format +suitable for any attached connectors. On some devices, it may be +possible to have a CRTC send data to more than one encoder. In that +case, both encoders would receive data from the same scanout buffer, +resulting in a "cloned" display configuration across the connectors +attached to each encoder. + +Encoder Initialization +^^^^^^^^^^^^^^^^^^^^^^ + +As for CRTCs, a KMS driver must create, initialize and register at least +one :c:type:`struct drm_encoder ` instance. The +instance is allocated and zeroed by the driver, possibly as part of a +larger structure. + +Drivers must initialize the :c:type:`struct drm_encoder +` possible_crtcs and possible_clones fields before +registering the encoder. Both fields are bitmasks of respectively the +CRTCs that the encoder can be connected to, and sibling encoders +candidate for cloning. + +After being initialized, the encoder must be registered with a call to +:c:func:`drm_encoder_init()`. The function takes a pointer to the +encoder functions and an encoder type. Supported types are + +- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A +- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort +- DRM_MODE_ENCODER_LVDS for display panels +- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, + Component, SCART) +- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays + +Encoders must be attached to a CRTC to be used. DRM drivers leave +encoders unattached at initialization time. Applications (or the fbdev +compatibility layer when implemented) are responsible for attaching the +encoders they want to use to a CRTC. + +Connectors (:c:type:`struct drm_connector `) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A connector is the final destination for pixel data on a device, and +usually connects directly to an external display device like a monitor +or laptop panel. A connector can only be attached to one encoder at a +time. The connector is also the structure where information about the +attached display is kept, so it contains fields for display data, EDID +data, DPMS & connection status, and information about modes supported on +the attached displays. + +Connector Initialization +^^^^^^^^^^^^^^^^^^^^^^^^ + +Finally a KMS driver must create, initialize, register and attach at +least one :c:type:`struct drm_connector ` +instance. The instance is created as other KMS objects and initialized +by setting the following fields. + +interlace_allowed + Whether the connector can handle interlaced modes. + +doublescan_allowed + Whether the connector can handle doublescan. + +display_info + Display information is filled from EDID information when a display + is detected. For non hot-pluggable displays such as flat panels in + embedded systems, the driver should initialize the + display_info.width_mm and display_info.height_mm fields with the + physical size of the display. + +polled + Connector polling mode, a combination of + + DRM_CONNECTOR_POLL_HPD + The connector generates hotplug events and doesn't need to be + periodically polled. The CONNECT and DISCONNECT flags must not + be set together with the HPD flag. + + DRM_CONNECTOR_POLL_CONNECT + Periodically poll the connector for connection. + + DRM_CONNECTOR_POLL_DISCONNECT + Periodically poll the connector for disconnection. + + Set to 0 for connectors that don't support connection status + discovery. + +The connector is then registered with a call to +:c:func:`drm_connector_init()` with a pointer to the connector +functions and a connector type, and exposed through sysfs with a call to +:c:func:`drm_connector_register()`. + +Supported connector types are + +- DRM_MODE_CONNECTOR_VGA +- DRM_MODE_CONNECTOR_DVII +- DRM_MODE_CONNECTOR_DVID +- DRM_MODE_CONNECTOR_DVIA +- DRM_MODE_CONNECTOR_Composite +- DRM_MODE_CONNECTOR_SVIDEO +- DRM_MODE_CONNECTOR_LVDS +- DRM_MODE_CONNECTOR_Component +- DRM_MODE_CONNECTOR_9PinDIN +- DRM_MODE_CONNECTOR_DisplayPort +- DRM_MODE_CONNECTOR_HDMIA +- DRM_MODE_CONNECTOR_HDMIB +- DRM_MODE_CONNECTOR_TV +- DRM_MODE_CONNECTOR_eDP +- DRM_MODE_CONNECTOR_VIRTUAL + +Connectors must be attached to an encoder to be used. For devices that +map connectors to encoders 1:1, the connector should be attached at +initialization time with a call to +:c:func:`drm_mode_connector_attach_encoder()`. The driver must +also set the :c:type:`struct drm_connector ` +encoder field to point to the attached encoder. + +Finally, drivers must initialize the connectors state change detection +with a call to :c:func:`drm_kms_helper_poll_init()`. If at least +one connector is pollable but can't generate hotplug interrupts +(indicated by the DRM_CONNECTOR_POLL_CONNECT and +DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will +automatically be queued to periodically poll for changes. Connectors +that can generate hotplug interrupts must be marked with the +DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must +call :c:func:`drm_helper_hpd_irq_event()`. The function will +queue a delayed work to check the state of all connectors, but no +periodic polling will be done. + +Connector Operations +^^^^^^^^^^^^^^^^^^^^ + + **Note** + + Unless otherwise state, all operations are mandatory. + +DPMS +'''' + +void (\*dpms)(struct drm_connector \*connector, int mode); +The DPMS operation sets the power state of a connector. The mode +argument is one of + +- DRM_MODE_DPMS_ON + +- DRM_MODE_DPMS_STANDBY + +- DRM_MODE_DPMS_SUSPEND + +- DRM_MODE_DPMS_OFF + +In all but DPMS_ON mode the encoder to which the connector is attached +should put the display in low-power mode by driving its signals +appropriately. If more than one connector is attached to the encoder +care should be taken not to change the power state of other displays as +a side effect. Low-power mode should be propagated to the encoders and +CRTCs when all related connectors are put in low-power mode. + +Modes +''''' + +int (\*fill_modes)(struct drm_connector \*connector, uint32_t +max_width, uint32_t max_height); +Fill the mode list with all supported modes for the connector. If the +``max_width`` and ``max_height`` arguments are non-zero, the +implementation must ignore all modes wider than ``max_width`` or higher +than ``max_height``. + +The connector must also fill in this operation its display_info +width_mm and height_mm fields with the connected display physical size +in millimeters. The fields should be set to 0 if the value isn't known +or is not applicable (for instance for projector devices). + +Connection Status +''''''''''''''''' + +The connection status is updated through polling or hotplug events when +supported (see ?). The status value is reported to userspace through +ioctls and must not be used inside the driver, as it only gets +initialized by a call to :c:func:`drm_mode_getconnector()` from +userspace. + +enum drm_connector_status (\*detect)(struct drm_connector +\*connector, bool force); +Check to see if anything is attached to the connector. The ``force`` +parameter is set to false whilst polling or to true when checking the +connector due to user request. ``force`` can be used by the driver to +avoid expensive, destructive operations during automated probing. + +Return connector_status_connected if something is connected to the +connector, connector_status_disconnected if nothing is connected and +connector_status_unknown if the connection state isn't known. + +Drivers should only return connector_status_connected if the +connection status has really been probed as connected. Connectors that +can't detect the connection status, or failed connection status probes, +should return connector_status_unknown. + +Cleanup +~~~~~~~ + +The DRM core manages its objects' lifetime. When an object is not needed +anymore the core calls its destroy function, which must clean up and +free every resource allocated for the object. Every +:c:func:`drm_\*_init()` call must be matched with a corresponding +:c:func:`drm_\*_cleanup()` call to cleanup CRTCs +(:c:func:`drm_crtc_cleanup()`), planes +(:c:func:`drm_plane_cleanup()`), encoders +(:c:func:`drm_encoder_cleanup()`) and connectors +(:c:func:`drm_connector_cleanup()`). Furthermore, connectors that +have been added to sysfs must be removed by a call to +:c:func:`drm_connector_unregister()` before calling +:c:func:`drm_connector_cleanup()`. + +Connectors state change detection must be cleanup up with a call to +:c:func:`drm_kms_helper_poll_fini()`. + +Output discovery and initialization example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + void intel_crt_init(struct drm_device *dev) + { + struct drm_connector *connector; + struct intel_output *intel_output; + + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) + return; + + connector = &intel_output->base; + drm_connector_init(dev, &intel_output->base, + &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); + + drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, + DRM_MODE_ENCODER_DAC); + + drm_mode_connector_attach_encoder(&intel_output->base, + &intel_output->enc); + + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } + + intel_output->type = INTEL_OUTPUT_ANALOG; + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); + drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); + + drm_connector_register(connector); + } + +In the example above (taken from the i915 driver), a CRTC, connector and +encoder combination is created. A device-specific i2c bus is also +created for fetching EDID data and performing monitor detection. Once +the process is complete, the new connector is registered with sysfs to +make its properties available to applications. + +KMS API Functions +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_crtc.c + :export: + +KMS Data Structures +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_crtc.h + :internal: + +KMS Locking +~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c + :doc: kms locking + +.. kernel-doc:: include/drm/drm_modeset_lock.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c + :export: + +Mode Setting Helper Functions +----------------------------- + +The plane, CRTC, encoder and connector functions provided by the drivers +implement the DRM API. They're called by the DRM core and ioctl handlers +to handle device state changes and configuration request. As +implementing those functions often requires logic not specific to +drivers, mid-layer helper functions are available to avoid duplicating +boilerplate code. + +The DRM core contains one mid-layer implementation. The mid-layer +provides implementations of several plane, CRTC, encoder and connector +functions (called from the top of the mid-layer) that pre-process +requests and call lower-level functions provided by the driver (at the +bottom of the mid-layer). For instance, the +:c:func:`drm_crtc_helper_set_config()` function can be used to +fill the :c:type:`struct drm_crtc_funcs ` +set_config field. When called, it will split the set_config operation +in smaller, simpler operations and call the driver to handle them. + +To use the mid-layer, drivers call +:c:func:`drm_crtc_helper_add()`, +:c:func:`drm_encoder_helper_add()` and +:c:func:`drm_connector_helper_add()` functions to install their +mid-layer bottom operations handlers, and fill the :c:type:`struct +drm_crtc_funcs `, :c:type:`struct +drm_encoder_funcs ` and :c:type:`struct +drm_connector_funcs ` structures with +pointers to the mid-layer top API functions. Installing the mid-layer +bottom operation handlers is best done right after registering the +corresponding KMS object. + +The mid-layer is not split between CRTC, encoder and connector +operations. To use it, a driver must provide bottom functions for all of +the three KMS entities. + +Atomic Modeset Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Overview +^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: overview + +Implementing Asynchronous Atomic Commit +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: implementing nonblocking commit + +Atomic State Reset and Initialization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: atomic state reset and initialization + +.. kernel-doc:: include/drm/drm_atomic_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :export: + +Modeset Helper Reference for Common Vtables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h + :internal: + +.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h + :doc: overview + +Legacy CRTC/Modeset Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c + :doc: overview + +Output Probing Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c + :doc: output probing helper overview + +.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c + :export: + +fbdev Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :doc: fbdev helpers + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :export: + +.. kernel-doc:: include/drm/drm_fb_helper.h + :internal: + +Framebuffer CMA Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c + :doc: framebuffer cma helper functions + +.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c + :export: + +Display Port Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c + :doc: dp helpers + +.. kernel-doc:: include/drm/drm_dp_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c + :export: + +Display Port Dual Mode Adaptor Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c + :doc: dp dual mode helpers + +.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c + :export: + +Display Port MST Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c + :doc: dp mst helper + +.. kernel-doc:: include/drm/drm_dp_mst_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c + :export: + +MIPI DSI Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c + :doc: dsi helpers + +.. kernel-doc:: include/drm/drm_mipi_dsi.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c + :export: + +EDID Helper Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_edid.c + :export: + +Rectangle Utilities Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_rect.h + :doc: rect utils + +.. kernel-doc:: include/drm/drm_rect.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_rect.c + :export: + +Flip-work Helper Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_flip_work.h + :doc: flip utils + +.. kernel-doc:: include/drm/drm_flip_work.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_flip_work.c + :export: + +HDMI Infoframes Helper Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Strictly speaking this is not a DRM helper library but generally useable +by any driver interfacing with HDMI outputs like v4l or alsa drivers. +But it nicely fits into the overall topic of mode setting helper +libraries and hence is also included here. + +.. kernel-doc:: include/linux/hdmi.h + :internal: + +.. kernel-doc:: drivers/video/hdmi.c + :export: + +Plane Helper Reference +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c + :doc: overview + +Tile group +~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_crtc.c + :doc: Tile group + +Bridges +~~~~~~~ + +Overview +^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: overview + +Default bridge callback sequence +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: bridge callbacks + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :export: + +Panel Helper Reference +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_panel.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :doc: drm panel + +Simple KMS Helper Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/drm/drm_simple_kms_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :doc: overview + +KMS Properties +-------------- + +Drivers may need to expose additional parameters to applications than +those described in the previous sections. KMS supports attaching +properties to CRTCs, connectors and planes and offers a userspace API to +list, get and set the property values. + +Properties are identified by a name that uniquely defines the property +purpose, and store an associated value. For all property types except +blob properties the value is a 64-bit unsigned integer. + +KMS differentiates between properties and property instances. Drivers +first create properties and then create and associate individual +instances of those properties to objects. A property can be instantiated +multiple times and associated with different objects. Values are stored +in property instances, and all other property information are stored in +the property and shared between all instances of the property. + +Every property is created with a type that influences how the KMS core +handles the property. Supported property types are + +DRM_MODE_PROP_RANGE + Range properties report their minimum and maximum admissible values. + The KMS core verifies that values set by application fit in that + range. + +DRM_MODE_PROP_ENUM + Enumerated properties take a numerical value that ranges from 0 to + the number of enumerated values defined by the property minus one, + and associate a free-formed string name to each value. Applications + can retrieve the list of defined value-name pairs and use the + numerical value to get and set property instance values. + +DRM_MODE_PROP_BITMASK + Bitmask properties are enumeration properties that additionally + restrict all enumerated values to the 0..63 range. Bitmask property + instance values combine one or more of the enumerated bits defined + by the property. + +DRM_MODE_PROP_BLOB + Blob properties store a binary blob without any format restriction. + The binary blobs are created as KMS standalone objects, and blob + property instance values store the ID of their associated blob + object. + + Blob properties are only used for the connector EDID property and + cannot be created by drivers. + +To create a property drivers call one of the following functions +depending on the property type. All property creation functions take +property flags and name, as well as type-specific arguments. + +- struct drm_property \*drm_property_create_range(struct + drm_device \*dev, int flags, const char \*name, uint64_t min, + uint64_t max); + Create a range property with the given minimum and maximum values. + +- struct drm_property \*drm_property_create_enum(struct drm_device + \*dev, int flags, const char \*name, const struct + drm_prop_enum_list \*props, int num_values); + Create an enumerated property. The ``props`` argument points to an + array of ``num_values`` value-name pairs. + +- struct drm_property \*drm_property_create_bitmask(struct + drm_device \*dev, int flags, const char \*name, const struct + drm_prop_enum_list \*props, int num_values); + Create a bitmask property. The ``props`` argument points to an array + of ``num_values`` value-name pairs. + +Properties can additionally be created as immutable, in which case they +will be read-only for applications but can be modified by the driver. To +create an immutable property drivers must set the +DRM_MODE_PROP_IMMUTABLE flag at property creation time. + +When no array of value-name pairs is readily available at property +creation time for enumerated or range properties, drivers can create the +property using the :c:func:`drm_property_create()` function and +manually add enumeration value-name pairs by calling the +:c:func:`drm_property_add_enum()` function. Care must be taken to +properly specify the property type through the ``flags`` argument. + +After creating properties drivers can attach property instances to CRTC, +connector and plane objects by calling the +:c:func:`drm_object_attach_property()`. The function takes a +pointer to the target object, a pointer to the previously created +property and an initial instance value. + +Existing KMS Properties +~~~~~~~~~~~~~~~~~~~~~~~ + +The following table gives description of drm properties exposed by +various modules/drivers. + ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Owner Module/Drivers | Group | Property Name | Type | Property Values | Object attached | Description/Restrictions | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DRM | Generic | “rotation” | BITMASK | { 0, "rotate-0" }, { 1, "rotate-90" }, { 2, "rotate-180" }, { 3, "rotate-270" }, { 4, "reflect-x" }, { 5, "reflect-y" } | CRTC, Plane | rotate-(degrees) rotates the image by the specified amount in degrees in counter clockwise direction. reflect-x and reflect-y reflects the image along the specified axis prior to rotation | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “scaling mode” | ENUM | { "None", "Full", "Center", "Full aspect" } | Connector | Supported by: amdgpu, gma500, i915, nouveau and radeon. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Connector | “EDID” | BLOB \| IMMUTABLE | 0 | Connector | Contains id of edid blob ptr object. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “DPMS” | ENUM | { “On”, “Standby”, “Suspend”, “Off” } | Connector | Contains DPMS operation mode value. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “PATH” | BLOB \| IMMUTABLE | 0 | Connector | Contains topology path to a connector. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “TILE” | BLOB \| IMMUTABLE | 0 | Connector | Contains tiling information for a connector. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Connector | CRTC that connector is attached to (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Plane | “type” | ENUM \| IMMUTABLE | { "Overlay", "Primary", "Cursor" } | Plane | Plane type | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_X” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source x coordinate in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_Y” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source y coordinate in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source width in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “SRC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source height in 16.16 fixed point (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_X” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) x coordinate (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_Y” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) y coordinate (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) width (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) height (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “FB_ID” | OBJECT | DRM_MODE_OBJECT_FB | Plane | Scanout framebuffer (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Plane | CRTC that plane is attached to (atomic) | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DVI-I | “subconnector” | ENUM | { “Unknown”, “DVI-D”, “DVI-A” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “select subconnector” | ENUM | { “Automatic”, “DVI-D”, “DVI-A” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| TV | “subconnector” | ENUM | { "Unknown", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “select subconnector” | ENUM | { "Automatic", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “left margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “right margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “top margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “bottom margin” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “brightness” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker reduction” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “overscan” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Virtual GPU | “suggested X” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an X offset for a connector | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “suggested Y” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an Y offset for a connector | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Optional | "aspect ratio" | ENUM | { "None", "4:3", "16:9" } | Connector | TDB | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dirty” | ENUM \| IMMUTABLE | { "Off", "On", "Annotate" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “DEGAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “DEGAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the DEGAMMA_LUT property (the size depends on the underlying hardware). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “CTM” | BLOB | 0 | CRTC | DRM property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is an interpreted as a struct drm_color_ctm. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “GAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the gamma lookup table (LUT) mapping pixel data after to the transformation matrix to data sent to the connector. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “GAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the GAMMA_LUT property (the size depends on the underlying hardware). | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| i915 | Generic | "Broadcast RGB" | ENUM | { "Automatic", "Full", "Limited 16:235" } | Connector | When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255. | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “audio” | ENUM | { "force-dvi", "off", "auto", "on" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| CDV gma-500 | Generic | "Broadcast RGB" | ENUM | { “Full”, “Limited 16:235” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "Broadcast RGB" | ENUM | { “off”, “auto”, “on” } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Poulsbo | Generic | “backlight” | RANGE | Min=0, Max=100 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| armada | CRTC | "CSC_YUV" | ENUM | { "Auto" , "CCIR601", "CCIR709" } | CRTC | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "CSC_RGB" | ENUM | { "Auto", "Computer system", "Studio" } | CRTC | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Overlay | "colorkey" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_min" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_max" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_val" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_alpha" | RANGE | Min=0, Max=0xffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey_mode" | ENUM | { "disabled", "Y component", "U component" , "V component", "RGB", “R component", "G component", "B component" } | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "brightness" | RANGE | Min=0, Max=256 + 255 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "contrast" | RANGE | Min=0, Max=0x7fff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "saturation" | RANGE | Min=0, Max=0x7fff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| exynos | CRTC | “mode” | ENUM | { "normal", "blank" } | CRTC | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Overlay | “zpos” | RANGE | Min=0, Max=MAX_PLANE-1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| i2c/ch7006_drv | Generic | “scale” | RANGE | Min=0, Max=2 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| TV | “mode” | ENUM | { "PAL", "PAL-M","PAL-N"}, ”PAL-Nc" , "PAL-60", "NTSC-M", "NTSC-J" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| nouveau | NV10 Overlay | "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “contrast” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “hue” | RANGE | Min=0, Max=359 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “saturation” | RANGE | Min=0, Max=8192-1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “iturbt_709” | RANGE | Min=0, Max=1 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Nv04 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Display | “dithering mode” | ENUM | { "auto", "off", "on" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “dithering depth” | ENUM | { "auto", "off", "on", "static 2x2", "dynamic 2x2", "temporal" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “underscan” | ENUM | { "auto", "6 bpc", "8 bpc" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “vibrant hue” | RANGE | Min=0, Max=180 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| “color vibrance” | RANGE | Min=0, Max=200 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| omap | Generic | “zorder” | RANGE | Min=0, Max=3 | CRTC, Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| qxl | Generic | “hotplug_mode_update" | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| radeon | DVI-I | “coherent” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DAC enable load detect | “load detection” | RANGE | Min=0, Max=1 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| TV Standard | "tv standard" | ENUM | { "ntsc", "pal", "pal-m", "pal-60", "ntsc-j" , "scart-pal", "pal-cn", "secam" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| legacy TMDS PLL detect | "tmds_pll" | ENUM | { "driver", "bios" } | - | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Underscan | "underscan" | ENUM | { "off", "on", "auto" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "underscan hborder" | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "underscan vborder" | RANGE | Min=0, Max=128 | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Audio | “audio” | ENUM | { "off", "on", "auto" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| FMT Dithering | “dither” | ENUM | { "off", "on" } | Connector | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| rcar-du | Generic | "alpha" | RANGE | Min=0, Max=255 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| "zpos" | RANGE | Min=1, Max=7 | Plane | TBD | ++-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Vertical Blanking +----------------- + +Vertical blanking plays a major role in graphics rendering. To achieve +tear-free display, users must synchronize page flips and/or rendering to +vertical blanking. The DRM API offers ioctls to perform page flips +synchronized to vertical blanking and wait for vertical blanking. + +The DRM core handles most of the vertical blanking management logic, +which involves filtering out spurious interrupts, keeping race-free +blanking counters, coping with counter wrap-around and resets and +keeping use counts. It relies on the driver to generate vertical +blanking interrupts and optionally provide a hardware vertical blanking +counter. Drivers must implement the following operations. + +- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void + (\*disable_vblank) (struct drm_device \*dev, int crtc); + Enable or disable vertical blanking interrupts for the given CRTC. + +- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); + Retrieve the value of the vertical blanking counter for the given + CRTC. If the hardware maintains a vertical blanking counter its value + should be returned. Otherwise drivers can use the + :c:func:`drm_vblank_count()` helper function to handle this + operation. + +Drivers must initialize the vertical blanking handling core with a call +to :c:func:`drm_vblank_init()` in their load operation. + +Vertical blanking interrupts can be enabled by the DRM core or by +drivers themselves (for instance to handle page flipping operations). +The DRM core maintains a vertical blanking use count to ensure that the +interrupts are not disabled while a user still needs them. To increment +the use count, drivers call :c:func:`drm_vblank_get()`. Upon +return vertical blanking interrupts are guaranteed to be enabled. + +To decrement the use count drivers call +:c:func:`drm_vblank_put()`. Only when the use count drops to zero +will the DRM core disable the vertical blanking interrupts after a delay +by scheduling a timer. The delay is accessible through the +vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global +variable and expressed in milliseconds. Its default value is 5000 ms. +Zero means never disable, and a negative value means disable +immediately. Drivers may override the behaviour by setting the +:c:type:`struct drm_device ` +vblank_disable_immediate flag, which when set causes vblank interrupts +to be disabled immediately regardless of the drm_vblank_offdelay +value. The flag should only be set if there's a properly working +hardware vblank counter present. + +When a vertical blanking interrupt occurs drivers only need to call the +:c:func:`drm_handle_vblank()` function to account for the +interrupt. + +Resources allocated by :c:func:`drm_vblank_init()` must be freed +with a call to :c:func:`drm_vblank_cleanup()` in the driver unload +operation handler. + +Vertical Blanking and Interrupt Handling Functions Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_irq.c + :export: + +.. kernel-doc:: include/drm/drmP.h + :functions: drm_crtc_vblank_waitqueue + +Open/Close, File Operations and IOCTLs +-------------------------------------- + +Open and Close +~~~~~~~~~~~~~~ + +int (\*firstopen) (struct drm_device \*); void (\*lastclose) (struct +drm_device \*); int (\*open) (struct drm_device \*, struct drm_file +\*); void (\*preclose) (struct drm_device \*, struct drm_file \*); +void (\*postclose) (struct drm_device \*, struct drm_file \*); + Open and close handlers. None of those methods are mandatory. + +The firstopen method is called by the DRM core for legacy UMS (User Mode +Setting) drivers only when an application opens a device that has no +other opened file handle. UMS drivers can implement it to acquire device +resources. KMS drivers can't use the method and must acquire resources +in the load method instead. + +Similarly the lastclose method is called when the last application +holding a file handle opened on the device closes it, for both UMS and +KMS drivers. Additionally, the method is also called at module unload +time or, for hot-pluggable devices, when the device is unplugged. The +firstopen and lastclose calls can thus be unbalanced. + +The open method is called every time the device is opened by an +application. Drivers can allocate per-file private data in this method +and store them in the struct :c:type:`struct drm_file +` driver_priv field. Note that the open method is +called before firstopen. + +The close operation is split into preclose and postclose methods. +Drivers must stop and cleanup all per-file operations in the preclose +method. For instance pending vertical blanking and page flip events must +be cancelled. No per-file operation is allowed on the file handle after +returning from the preclose method. + +Finally the postclose method is called as the last step of the close +operation, right before calling the lastclose method if no other open +file handle exists for the device. Drivers that have allocated per-file +private data in the open method should free it here. + +The lastclose method should restore CRTC and plane properties to default +value, so that a subsequent open of the device will not inherit state +from the previous user. It can also be used to execute delayed power +switching state changes, e.g. in conjunction with the vga_switcheroo +infrastructure (see ?). Beyond that KMS drivers should not do any +further cleanup. Only legacy UMS drivers might need to clean up device +state so that the vga console or an independent fbdev driver could take +over. + +File Operations +~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_fops.c + :doc: file operations + +.. kernel-doc:: drivers/gpu/drm/drm_fops.c + :export: + +IOCTLs +~~~~~~ + +struct drm_ioctl_desc \*ioctls; int num_ioctls; + Driver-specific ioctls descriptors table. + +Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls +descriptors table is indexed by the ioctl number offset from the base +value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize +the table entries. + +:: + + DRM_IOCTL_DEF_DRV(ioctl, func, flags) + +``ioctl`` is the ioctl name. Drivers must define the DRM_##ioctl and +DRM_IOCTL_##ioctl macros to the ioctl number offset from +DRM_COMMAND_BASE and the ioctl number respectively. The first macro is +private to the device while the second must be exposed to userspace in a +public header. + +``func`` is a pointer to the ioctl handler function compatible with the +``drm_ioctl_t`` type. + +:: + + typedef int drm_ioctl_t(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +``flags`` is a bitmask combination of the following values. It restricts +how the ioctl is allowed to be called. + +- DRM_AUTH - Only authenticated callers allowed + +- DRM_MASTER - The ioctl can only be called on the master file handle + +- DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed + +- DRM_CONTROL_ALLOW - The ioctl can only be called on a control + device + +- DRM_UNLOCKED - The ioctl handler will be called without locking the + DRM global mutex. This is the enforced default for kms drivers (i.e. + using the DRIVER_MODESET flag) and hence shouldn't be used any more + for new drivers. + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :export: + +Legacy Support Code +------------------- + +The section very briefly covers some of the old legacy support code +which is only used by old DRM drivers which have done a so-called +shadow-attach to the underlying device instead of registering as a real +driver. This also includes some of the old generic buffer management and +command submission code. Do not use any of this in new and modern +drivers. + +Legacy Suspend/Resume +~~~~~~~~~~~~~~~~~~~~~ + +The DRM core provides some suspend/resume code, but drivers wanting full +suspend/resume support should provide save() and restore() functions. +These are called at suspend, hibernate, or resume time, and should +perform any state save or restore required by your device across suspend +or hibernate states. + +int (\*suspend) (struct drm_device \*, pm_message_t state); int +(\*resume) (struct drm_device \*); +Those are legacy suspend and resume methods which *only* work with the +legacy shadow-attach driver registration functions. New driver should +use the power management interface provided by their bus type (usually +through the :c:type:`struct device_driver ` +dev_pm_ops) and set these methods to NULL. + +Legacy DMA Services +~~~~~~~~~~~~~~~~~~~ + +This should cover how DMA mapping etc. is supported by the core. These +functions are deprecated and should not be used. diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst new file mode 100644 index 000000000000..3b667b1992e5 --- /dev/null +++ b/Documentation/gpu/drm-uapi.rst @@ -0,0 +1,91 @@ +Userland interfaces +=================== + +The DRM core exports several interfaces to applications, generally +intended to be used through corresponding libdrm wrapper functions. In +addition, drivers export device-specific interfaces for use by userspace +drivers & device-aware applications through ioctls and sysfs files. + +External interfaces include: memory mapping, context management, DMA +operations, AGP management, vblank control, fence management, memory +management, and output management. + +Cover generic ioctls and sysfs layout here. We only need high-level +info, since man pages should cover the rest. + +Render nodes +------------ + +DRM core provides multiple character-devices for user-space to use. +Depending on which device is opened, user-space can perform a different +set of operations (mainly ioctls). The primary node is always created +and called card. Additionally, a currently unused control node, +called controlD is also created. The primary node provides all +legacy operations and historically was the only interface used by +userspace. With KMS, the control node was introduced. However, the +planned KMS control interface has never been written and so the control +node stays unused to date. + +With the increased use of offscreen renderers and GPGPU applications, +clients no longer require running compositors or graphics servers to +make use of a GPU. But the DRM API required unprivileged clients to +authenticate to a DRM-Master prior to getting GPU access. To avoid this +step and to grant clients GPU access without authenticating, render +nodes were introduced. Render nodes solely serve render clients, that +is, no modesetting or privileged ioctls can be issued on render nodes. +Only non-global rendering commands are allowed. If a driver supports +render nodes, it must advertise it via the DRIVER_RENDER DRM driver +capability. If not supported, the primary node must be used for render +clients together with the legacy drmAuth authentication procedure. + +If a driver advertises render node support, DRM core will create a +separate render node called renderD. There will be one render node +per device. No ioctls except PRIME-related ioctls will be allowed on +this node. Especially GEM_OPEN will be explicitly prohibited. Render +nodes are designed to avoid the buffer-leaks, which occur if clients +guess the flink names or mmap offsets on the legacy interface. +Additionally to this basic interface, drivers must mark their +driver-dependent render-only ioctls as DRM_RENDER_ALLOW so render +clients can use them. Driver authors must be careful not to allow any +privileged ioctls on render nodes. + +With render nodes, user-space can now control access to the render node +via basic file-system access-modes. A running graphics server which +authenticates clients on the privileged primary/legacy node is no longer +required. Instead, a client can open the render node and is immediately +granted GPU access. Communication between clients (or servers) is done +via PRIME. FLINK from render node to legacy node is not supported. New +clients must not use the insecure FLINK interface. + +Besides dropping all modeset/global ioctls, render nodes also drop the +DRM-Master concept. There is no reason to associate render clients with +a DRM-Master as they are independent of any graphics server. Besides, +they must work without any running master, anyway. Drivers must be able +to run without a master object if they support render nodes. If, on the +other hand, a driver requires shared state between clients which is +visible to user-space and accessible beyond open-file boundaries, they +cannot support render nodes. + +VBlank event handling +--------------------- + +The DRM core exposes two vertical blank related ioctls: + +DRM_IOCTL_WAIT_VBLANK + This takes a struct drm_wait_vblank structure as its argument, and + it is used to block or request a signal when a specified vblank + event occurs. + +DRM_IOCTL_MODESET_CTL + This was only used for user-mode-settind drivers around modesetting + changes to allow the kernel to update the vblank interrupt after + mode setting, since on many devices the vertical blank counter is + reset to 0 at some point during modeset. Modern drivers should not + call this any more since with kernel mode setting it is a no-op. + +This second part of the GPU Driver Developer's Guide documents driver +code, implementation details and also all the driver-specific userspace +interfaces. Especially since all hardware-acceleration interfaces to +userspace are driver specific for efficiency and other reasons these +interfaces can be rather substantial. Hence every driver has its own +chapter. diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst new file mode 100644 index 000000000000..9c6732123c3c --- /dev/null +++ b/Documentation/gpu/i915.rst @@ -0,0 +1,346 @@ +drm/i915 Intel GFX Driver +========================= + +The drm/i915 driver supports all (with the exception of some very early +models) integrated GFX chipsets with both Intel display and rendering +blocks. This excludes a set of SoC platforms with an SGX rendering unit, +those have basic support through the gma500 drm driver. + +Core Driver Infrastructure +-------------------------- + +This section covers core driver infrastructure used by both the display +and the GEM parts of the driver. + +Runtime Power Management +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c + :doc: runtime pm + +.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/intel_uncore.c + :internal: + +Interrupt Handling +~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :doc: interrupt handling + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :functions: intel_irq_init intel_irq_init_hw intel_hpd_init + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :functions: intel_runtime_pm_disable_interrupts + +.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c + :functions: intel_runtime_pm_enable_interrupts + +Intel GVT-g Guest Support(vGPU) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c + :doc: Intel GVT-g guest support + +.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c + :internal: + +Display Hardware Handling +------------------------- + +This section covers everything related to the display hardware including +the mode setting infrastructure, plane, sprite and cursor handling and +display, output probing and related topics. + +Mode Setting Infrastructure +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The i915 driver is thus far the only DRM driver which doesn't use the +common DRM helper code to implement mode setting sequences. Thus it has +its own tailor-made infrastructure for executing a display configuration +change. + +Frontbuffer Tracking +~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c + :doc: frontbuffer tracking + +.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem.c + :functions: i915_gem_track_fb + +Display FIFO Underrun Reporting +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c + :doc: fifo underrun handling + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c + :internal: + +Plane Configuration +~~~~~~~~~~~~~~~~~~~ + +This section covers plane configuration and composition with the primary +plane, sprites, cursors and overlays. This includes the infrastructure +to do atomic vsync'ed updates of all this state and also tightly coupled +topics like watermark setup and computation, framebuffer compression and +panel self refresh. + +Atomic Plane Helpers +~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c + :doc: atomic plane helpers + +.. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c + :internal: + +Output Probing +~~~~~~~~~~~~~~ + +This section covers output probing and related infrastructure like the +hotplug interrupt storm detection and mitigation code. Note that the +i915 driver still uses most of the common DRM helper code for output +probing, so those sections fully apply. + +Hotplug +~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c + :doc: Hotplug + +.. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c + :internal: + +High Definition Audio +~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :doc: High Definition Audio over HDMI and Display Port + +.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :internal: + +.. kernel-doc:: include/drm/i915_component.h + :internal: + +Panel Self Refresh PSR (PSR/SRD) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c + :doc: Panel Self Refresh (PSR/SRD) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c + :internal: + +Frame Buffer Compression (FBC) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c + :doc: Frame Buffer Compression (FBC) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c + :internal: + +Display Refresh Rate Switching (DRRS) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :doc: Display Refresh Rate Switching (DRRS) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_dp_set_drrs_state + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_enable + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_disable + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_invalidate + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_edp_drrs_flush + +.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c + :functions: intel_dp_drrs_init + +DPIO +~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h + :doc: DPIO + +CSR firmware support for DMC +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c + :doc: csr support for dmc + +.. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c + :internal: + +Video BIOS Table (VBT) +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c + :doc: Video BIOS Table (VBT) + +.. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/intel_vbt_defs.h + :internal: + +Memory Management and Command Submission +---------------------------------------- + +This sections covers all things related to the GEM implementation in the +i915 driver. + +Batchbuffer Parsing +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c + :doc: batch buffer command parser + +.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c + :internal: + +Batchbuffer Pools +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c + :doc: batch pool + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c + :internal: + +Logical Rings, Logical Ring Contexts and Execlists +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c + :doc: Logical Rings, Logical Ring Contexts and Execlists + +.. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c + :internal: + +Global GTT views +~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c + :doc: Global GTT views + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c + :internal: + +GTT Fences and Swizzling +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c + :internal: + +Global GTT Fence Handling +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c + :doc: fence register handling + +Hardware Tiling and Swizzling Details +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c + :doc: tiling swizzling details + +Object Tiling IOCTLs +~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c + :internal: + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c + :doc: buffer object tiling + +Buffer Object Eviction +~~~~~~~~~~~~~~~~~~~~~~ + +This section documents the interface functions for evicting buffer +objects to make space available in the virtual gpu address spaces. Note +that this is mostly orthogonal to shrinking buffer objects caches, which +has the goal to make main memory (shared with the gpu through the +unified memory architecture) available. + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_evict.c + :internal: + +Buffer Object Memory Shrinking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section documents the interface function for shrinking memory usage +of buffer object caches. Shrinking is used to make main memory +available. Note that this is mostly orthogonal to evicting buffer +objects, which has the goal to make space in gpu virtual address spaces. + +.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_shrinker.c + :internal: + +GuC +--- + +GuC-specific firmware loader +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c + :doc: GuC-specific firmware loader + +.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c + :internal: + +GuC-based command submission +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c + :doc: GuC-based command submission + +.. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c + :internal: + +GuC Firmware Layout +~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fwif.h + :doc: GuC Firmware Layout + +Tracing +------- + +This sections covers all things related to the tracepoints implemented +in the i915 driver. + +i915_ppgtt_create and i915_ppgtt_release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h + :doc: i915_ppgtt_create and i915_ppgtt_release tracepoints + +i915_context_create and i915_context_free +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h + :doc: i915_context_create and i915_context_free tracepoints + +switch_mm +~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h + :doc: switch_mm tracepoint + +.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/drm/i915/i915_irq.c diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index 795a5ec309e2..e6b38e8e57c9 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -2,2600 +2,10 @@ Linux GPU Driver Developer's Guide ================================== -:Author: Jesse Barnes Initial version -:Author: Laurent Pinchart Driver internals -:Author: Daniel Vetter Contributions all over the place -:Author: Lukas Wunner vga_switcheroo documentation -:Date: 2015-10-11 +.. toctree:: -This first part of the GPU Driver Developer's Guide documents core DRM -code, helper libraries for writing drivers and generic userspace -interfaces exposed by DRM drivers. - -Introduction -============ - -The Linux DRM layer contains code intended to support the needs of -complex graphics devices, usually containing programmable pipelines well -suited to 3D graphics acceleration. Graphics drivers in the kernel may -make use of DRM functions to make tasks like memory management, -interrupt handling and DMA easier, and provide a uniform interface to -applications. - -A note on versions: this guide covers features found in the DRM tree, -including the TTM memory manager, output configuration and mode setting, -and the new vblank internals, in addition to all the regular features -found in current kernels. - -[Insert diagram of typical DRM stack here] - -Style Guidelines ----------------- - -For consistency this documentation uses American English. Abbreviations -are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so -on. To aid in reading, documentations make full use of the markup -characters kerneldoc provides: @parameter for function parameters, -@member for structure members, &structure to reference structures and -function() for functions. These all get automatically hyperlinked if -kerneldoc for the referenced objects exists. When referencing entries in -function vtables please use ->vfunc(). Note that kerneldoc does not -support referencing struct members directly, so please add a reference -to the vtable struct somewhere in the same paragraph or at least -section. - -Except in special situations (to separate locked from unlocked variants) -locking requirements for functions aren't documented in the kerneldoc. -Instead locking should be check at runtime using e.g. -``WARN_ON(!mutex_is_locked(...));``. Since it's much easier to ignore -documentation than runtime noise this provides more value. And on top of -that runtime checks do need to be updated when the locking rules change, -increasing the chances that they're correct. Within the documentation -the locking rules should be explained in the relevant structures: Either -in the comment for the lock explaining what it protects, or data fields -need a note about which lock protects them, or both. - -Functions which have a non-\ ``void`` return value should have a section -called "Returns" explaining the expected return values in different -cases and their meanings. Currently there's no consensus whether that -section name should be all upper-case or not, and whether it should end -in a colon or not. Go with the file-local style. Other common section -names are "Notes" with information for dangerous or tricky corner cases, -and "FIXME" where the interface could be cleaned up. - -DRM Internals -============= - -This chapter documents DRM internals relevant to driver authors and -developers working to add support for the latest features to existing -drivers. - -First, we go over some typical driver initialization requirements, like -setting up command buffers, creating an initial output configuration, -and initializing core services. Subsequent sections cover core internals -in more detail, providing implementation notes and examples. - -The DRM layer provides several services to graphics drivers, many of -them driven by the application interfaces it provides through libdrm, -the library that wraps most of the DRM ioctls. These include vblank -event handling, memory management, output management, framebuffer -management, command submission & fencing, suspend/resume support, and -DMA services. - -Driver Initialization ---------------------- - -At the core of every DRM driver is a :c:type:`struct drm_driver -` structure. Drivers typically statically initialize -a drm_driver structure, and then pass it to -:c:func:`drm_dev_alloc()` to allocate a device instance. After the -device instance is fully initialized it can be registered (which makes -it accessible from userspace) using :c:func:`drm_dev_register()`. - -The :c:type:`struct drm_driver ` structure -contains static information that describes the driver and features it -supports, and pointers to methods that the DRM core will call to -implement the DRM API. We will first go through the :c:type:`struct -drm_driver ` static information fields, and will -then describe individual operations in details as they get used in later -sections. - -Driver Information -~~~~~~~~~~~~~~~~~~ - -Driver Features -^^^^^^^^^^^^^^^ - -Drivers inform the DRM core about their requirements and supported -features by setting appropriate flags in the driver_features field. -Since those flags influence the DRM core behaviour since registration -time, most of them must be set to registering the :c:type:`struct -drm_driver ` instance. - -u32 driver_features; - -DRIVER_USE_AGP - Driver uses AGP interface, the DRM core will manage AGP resources. - -DRIVER_REQUIRE_AGP - Driver needs AGP interface to function. AGP initialization failure - will become a fatal error. - -DRIVER_PCI_DMA - Driver is capable of PCI DMA, mapping of PCI DMA buffers to - userspace will be enabled. Deprecated. - -DRIVER_SG - Driver can perform scatter/gather DMA, allocation and mapping of - scatter/gather buffers will be enabled. Deprecated. - -DRIVER_HAVE_DMA - Driver supports DMA, the userspace DMA API will be supported. - Deprecated. - -DRIVER_HAVE_IRQ; DRIVER_IRQ_SHARED - DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler - managed by the DRM Core. The core will support simple IRQ handler - installation when the flag is set. The installation process is - described in ?. - - DRIVER_IRQ_SHARED indicates whether the device & handler support - shared IRQs (note that this is required of PCI drivers). - -DRIVER_GEM - Driver use the GEM memory manager. - -DRIVER_MODESET - Driver supports mode setting interfaces (KMS). - -DRIVER_PRIME - Driver implements DRM PRIME buffer sharing. - -DRIVER_RENDER - Driver supports dedicated render nodes. - -DRIVER_ATOMIC - Driver supports atomic properties. In this case the driver must - implement appropriate obj->atomic_get_property() vfuncs for any - modeset objects with driver specific properties. - -Major, Minor and Patchlevel -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -int major; int minor; int patchlevel; -The DRM core identifies driver versions by a major, minor and patch -level triplet. The information is printed to the kernel log at -initialization time and passed to userspace through the -DRM_IOCTL_VERSION ioctl. - -The major and minor numbers are also used to verify the requested driver -API version passed to DRM_IOCTL_SET_VERSION. When the driver API -changes between minor versions, applications can call -DRM_IOCTL_SET_VERSION to select a specific version of the API. If the -requested major isn't equal to the driver major, or the requested minor -is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will -return an error. Otherwise the driver's set_version() method will be -called with the requested version. - -Name, Description and Date -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -char \*name; char \*desc; char \*date; -The driver name is printed to the kernel log at initialization time, -used for IRQ registration and passed to userspace through -DRM_IOCTL_VERSION. - -The driver description is a purely informative string passed to -userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by -the kernel. - -The driver date, formatted as YYYYMMDD, is meant to identify the date of -the latest modification to the driver. However, as most drivers fail to -update it, its value is mostly useless. The DRM core prints it to the -kernel log at initialization time and passes it to userspace through the -DRM_IOCTL_VERSION ioctl. - -Device Instance and Driver Handling -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_drv.c - :doc: driver instance overview - -.. kernel-doc:: drivers/gpu/drm/drm_drv.c - :export: - -Driver Load -~~~~~~~~~~~ - -IRQ Registration -^^^^^^^^^^^^^^^^ - -The DRM core tries to facilitate IRQ handler registration and -unregistration by providing :c:func:`drm_irq_install()` and -:c:func:`drm_irq_uninstall()` functions. Those functions only -support a single interrupt per device, devices that use more than one -IRQs need to be handled manually. - -Managed IRQ Registration -'''''''''''''''''''''''' - -:c:func:`drm_irq_install()` starts by calling the irq_preinstall -driver operation. The operation is optional and must make sure that the -interrupt will not get fired by clearing all pending interrupt flags or -disabling the interrupt. - -The passed-in IRQ will then be requested by a call to -:c:func:`request_irq()`. If the DRIVER_IRQ_SHARED driver feature -flag is set, a shared (IRQF_SHARED) IRQ handler will be requested. - -The IRQ handler function must be provided as the mandatory irq_handler -driver operation. It will get passed directly to -:c:func:`request_irq()` and thus has the same prototype as all IRQ -handlers. It will get called with a pointer to the DRM device as the -second argument. - -Finally the function calls the optional irq_postinstall driver -operation. The operation usually enables interrupts (excluding the -vblank interrupt, which is enabled separately), but drivers may choose -to enable/disable interrupts at a different time. - -:c:func:`drm_irq_uninstall()` is similarly used to uninstall an -IRQ handler. It starts by waking up all processes waiting on a vblank -interrupt to make sure they don't hang, and then calls the optional -irq_uninstall driver operation. The operation must disable all hardware -interrupts. Finally the function frees the IRQ by calling -:c:func:`free_irq()`. - -Manual IRQ Registration -''''''''''''''''''''''' - -Drivers that require multiple interrupt handlers can't use the managed -IRQ registration functions. In that case IRQs must be registered and -unregistered manually (usually with the :c:func:`request_irq()` and -:c:func:`free_irq()` functions, or their devm_\* equivalent). - -When manually registering IRQs, drivers must not set the -DRIVER_HAVE_IRQ driver feature flag, and must not provide the -irq_handler driver operation. They must set the :c:type:`struct -drm_device ` irq_enabled field to 1 upon -registration of the IRQs, and clear it to 0 after unregistering the -IRQs. - -Memory Manager Initialization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Every DRM driver requires a memory manager which must be initialized at -load time. DRM currently contains two memory managers, the Translation -Table Manager (TTM) and the Graphics Execution Manager (GEM). This -document describes the use of the GEM memory manager only. See ? for -details. - -Miscellaneous Device Configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Another task that may be necessary for PCI devices during configuration -is mapping the video BIOS. On many devices, the VBIOS describes device -configuration, LCD panel timings (if any), and contains flags indicating -device state. Mapping the BIOS can be done using the pci_map_rom() -call, a convenience function that takes care of mapping the actual ROM, -whether it has been shadowed into memory (typically at address 0xc0000) -or exists on the PCI device in the ROM BAR. Note that after the ROM has -been mapped and any necessary information has been extracted, it should -be unmapped; on many devices, the ROM address decoder is shared with -other BARs, so leaving it mapped could cause undesired behaviour like -hangs or memory corruption. - -Bus-specific Device Registration and PCI Support -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A number of functions are provided to help with device registration. The -functions deal with PCI and platform devices respectively and are only -provided for historical reasons. These are all deprecated and shouldn't -be used in new drivers. Besides that there's a few helpers for pci -drivers. - -.. kernel-doc:: drivers/gpu/drm/drm_pci.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_platform.c - :export: - -Memory management ------------------ - -Modern Linux systems require large amount of graphics memory to store -frame buffers, textures, vertices and other graphics-related data. Given -the very dynamic nature of many of that data, managing graphics memory -efficiently is thus crucial for the graphics stack and plays a central -role in the DRM infrastructure. - -The DRM core includes two memory managers, namely Translation Table Maps -(TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory -manager to be developed and tried to be a one-size-fits-them all -solution. It provides a single userspace API to accommodate the need of -all hardware, supporting both Unified Memory Architecture (UMA) devices -and devices with dedicated video RAM (i.e. most discrete video cards). -This resulted in a large, complex piece of code that turned out to be -hard to use for driver development. - -GEM started as an Intel-sponsored project in reaction to TTM's -complexity. Its design philosophy is completely different: instead of -providing a solution to every graphics memory-related problems, GEM -identified common code between drivers and created a support library to -share it. GEM has simpler initialization and execution requirements than -TTM, but has no video RAM management capabilities and is thus limited to -UMA devices. - -The Translation Table Manager (TTM) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -TTM design background and information belongs here. - -TTM initialization -^^^^^^^^^^^^^^^^^^ - - **Warning** - - This section is outdated. - -Drivers wishing to support TTM must fill out a drm_bo_driver -structure. The structure contains several fields with function pointers -for initializing the TTM, allocating and freeing memory, waiting for -command completion and fence synchronization, and memory migration. See -the radeon_ttm.c file for an example of usage. - -The ttm_global_reference structure is made up of several fields: - -:: - - struct ttm_global_reference { - enum ttm_global_types global_type; - size_t size; - void *object; - int (*init) (struct ttm_global_reference *); - void (*release) (struct ttm_global_reference *); - }; - - -There should be one global reference structure for your memory manager -as a whole, and there will be others for each object created by the -memory manager at runtime. Your global TTM should have a type of -TTM_GLOBAL_TTM_MEM. The size field for the global object should be -sizeof(struct ttm_mem_global), and the init and release hooks should -point at your driver-specific init and release routines, which probably -eventually call ttm_mem_global_init and ttm_mem_global_release, -respectively. - -Once your global TTM accounting structure is set up and initialized by -calling ttm_global_item_ref() on it, you need to create a buffer -object TTM to provide a pool for buffer object allocation by clients and -the kernel itself. The type of this object should be -TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct -ttm_bo_global). Again, driver-specific init and release functions may -be provided, likely eventually calling ttm_bo_global_init() and -ttm_bo_global_release(), respectively. Also, like the previous -object, ttm_global_item_ref() is used to create an initial reference -count for the TTM, which will call your initialization function. - -The Graphics Execution Manager (GEM) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The GEM design approach has resulted in a memory manager that doesn't -provide full coverage of all (or even all common) use cases in its -userspace or kernel API. GEM exposes a set of standard memory-related -operations to userspace and a set of helper functions to drivers, and -let drivers implement hardware-specific operations with their own -private API. - -The GEM userspace API is described in the `GEM - the Graphics Execution -Manager `__ article on LWN. While -slightly outdated, the document provides a good overview of the GEM API -principles. Buffer allocation and read and write operations, described -as part of the common GEM API, are currently implemented using -driver-specific ioctls. - -GEM is data-agnostic. It manages abstract buffer objects without knowing -what individual buffers contain. APIs that require knowledge of buffer -contents or purpose, such as buffer allocation or synchronization -primitives, are thus outside of the scope of GEM and must be implemented -using driver-specific ioctls. - -On a fundamental level, GEM involves several operations: - -- Memory allocation and freeing -- Command execution -- Aperture management at command execution time - -Buffer object allocation is relatively straightforward and largely -provided by Linux's shmem layer, which provides memory to back each -object. - -Device-specific operations, such as command execution, pinning, buffer -read & write, mapping, and domain ownership transfers are left to -driver-specific ioctls. - -GEM Initialization -^^^^^^^^^^^^^^^^^^ - -Drivers that use GEM must set the DRIVER_GEM bit in the struct -:c:type:`struct drm_driver ` driver_features -field. The DRM core will then automatically initialize the GEM core -before calling the load operation. Behind the scene, this will create a -DRM Memory Manager object which provides an address space pool for -object allocation. - -In a KMS configuration, drivers need to allocate and initialize a -command ring buffer following core GEM initialization if required by the -hardware. UMA devices usually have what is called a "stolen" memory -region, which provides space for the initial framebuffer and large, -contiguous memory regions required by the device. This space is -typically not managed by GEM, and must be initialized separately into -its own DRM MM object. - -GEM Objects Creation -^^^^^^^^^^^^^^^^^^^^ - -GEM splits creation of GEM objects and allocation of the memory that -backs them in two distinct operations. - -GEM objects are represented by an instance of struct :c:type:`struct -drm_gem_object `. Drivers usually need to -extend GEM objects with private information and thus create a -driver-specific GEM object structure type that embeds an instance of -struct :c:type:`struct drm_gem_object `. - -To create a GEM object, a driver allocates memory for an instance of its -specific GEM object type and initializes the embedded struct -:c:type:`struct drm_gem_object ` with a call -to :c:func:`drm_gem_object_init()`. The function takes a pointer -to the DRM device, a pointer to the GEM object and the buffer object -size in bytes. - -GEM uses shmem to allocate anonymous pageable memory. -:c:func:`drm_gem_object_init()` will create an shmfs file of the -requested size and store it into the struct :c:type:`struct -drm_gem_object ` filp field. The memory is -used as either main storage for the object when the graphics hardware -uses system memory directly or as a backing store otherwise. - -Drivers are responsible for the actual physical pages allocation by -calling :c:func:`shmem_read_mapping_page_gfp()` for each page. -Note that they can decide to allocate pages when initializing the GEM -object, or to delay allocation until the memory is needed (for instance -when a page fault occurs as a result of a userspace memory access or -when the driver needs to start a DMA transfer involving the memory). - -Anonymous pageable memory allocation is not always desired, for instance -when the hardware requires physically contiguous system memory as is -often the case in embedded devices. Drivers can create GEM objects with -no shmfs backing (called private GEM objects) by initializing them with -a call to :c:func:`drm_gem_private_object_init()` instead of -:c:func:`drm_gem_object_init()`. Storage for private GEM objects -must be managed by drivers. - -GEM Objects Lifetime -^^^^^^^^^^^^^^^^^^^^ - -All GEM objects are reference-counted by the GEM core. References can be -acquired and release by :c:func:`calling -drm_gem_object_reference()` and -:c:func:`drm_gem_object_unreference()` respectively. The caller -must hold the :c:type:`struct drm_device ` -struct_mutex lock when calling -:c:func:`drm_gem_object_reference()`. As a convenience, GEM -provides :c:func:`drm_gem_object_unreference_unlocked()` -functions that can be called without holding the lock. - -When the last reference to a GEM object is released the GEM core calls -the :c:type:`struct drm_driver ` gem_free_object -operation. That operation is mandatory for GEM-enabled drivers and must -free the GEM object and all associated resources. - -void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are -responsible for freeing all GEM object resources. This includes the -resources created by the GEM core, which need to be released with -:c:func:`drm_gem_object_release()`. - -GEM Objects Naming -^^^^^^^^^^^^^^^^^^ - -Communication between userspace and the kernel refers to GEM objects -using local handles, global names or, more recently, file descriptors. -All of those are 32-bit integer values; the usual Linux kernel limits -apply to the file descriptors. - -GEM handles are local to a DRM file. Applications get a handle to a GEM -object through a driver-specific ioctl, and can use that handle to refer -to the GEM object in other standard or driver-specific ioctls. Closing a -DRM file handle frees all its GEM handles and dereferences the -associated GEM objects. - -To create a handle for a GEM object drivers call -:c:func:`drm_gem_handle_create()`. The function takes a pointer -to the DRM file and the GEM object and returns a locally unique handle. -When the handle is no longer needed drivers delete it with a call to -:c:func:`drm_gem_handle_delete()`. Finally the GEM object -associated with a handle can be retrieved by a call to -:c:func:`drm_gem_object_lookup()`. - -Handles don't take ownership of GEM objects, they only take a reference -to the object that will be dropped when the handle is destroyed. To -avoid leaking GEM objects, drivers must make sure they drop the -reference(s) they own (such as the initial reference taken at object -creation time) as appropriate, without any special consideration for the -handle. For example, in the particular case of combined GEM object and -handle creation in the implementation of the dumb_create operation, -drivers must drop the initial reference to the GEM object before -returning the handle. - -GEM names are similar in purpose to handles but are not local to DRM -files. They can be passed between processes to reference a GEM object -globally. Names can't be used directly to refer to objects in the DRM -API, applications must convert handles to names and names to handles -using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls -respectively. The conversion is handled by the DRM core without any -driver-specific support. - -GEM also supports buffer sharing with dma-buf file descriptors through -PRIME. GEM-based drivers must use the provided helpers functions to -implement the exporting and importing correctly. See ?. Since sharing -file descriptors is inherently more secure than the easily guessable and -global GEM names it is the preferred buffer sharing mechanism. Sharing -buffers through GEM names is only supported for legacy userspace. -Furthermore PRIME also allows cross-device buffer sharing since it is -based on dma-bufs. - -GEM Objects Mapping -^^^^^^^^^^^^^^^^^^^ - -Because mapping operations are fairly heavyweight GEM favours -read/write-like access to buffers, implemented through driver-specific -ioctls, over mapping buffers to userspace. However, when random access -to the buffer is needed (to perform software rendering for instance), -direct access to the object can be more efficient. - -The mmap system call can't be used directly to map GEM objects, as they -don't have their own file handle. Two alternative methods currently -co-exist to map GEM objects to userspace. The first method uses a -driver-specific ioctl to perform the mapping operation, calling -:c:func:`do_mmap()` under the hood. This is often considered -dubious, seems to be discouraged for new GEM-enabled drivers, and will -thus not be described here. - -The second method uses the mmap system call on the DRM file handle. void -\*mmap(void \*addr, size_t length, int prot, int flags, int fd, off_t -offset); DRM identifies the GEM object to be mapped by a fake offset -passed through the mmap offset argument. Prior to being mapped, a GEM -object must thus be associated with a fake offset. To do so, drivers -must call :c:func:`drm_gem_create_mmap_offset()` on the object. - -Once allocated, the fake offset value must be passed to the application -in a driver-specific way and can then be used as the mmap offset -argument. - -The GEM core provides a helper method :c:func:`drm_gem_mmap()` to -handle object mapping. The method can be set directly as the mmap file -operation handler. It will look up the GEM object based on the offset -value and set the VMA operations to the :c:type:`struct drm_driver -` gem_vm_ops field. Note that -:c:func:`drm_gem_mmap()` doesn't map memory to userspace, but -relies on the driver-provided fault handler to map pages individually. - -To use :c:func:`drm_gem_mmap()`, drivers must fill the struct -:c:type:`struct drm_driver ` gem_vm_ops field -with a pointer to VM operations. - -struct vm_operations_struct \*gem_vm_ops struct -vm_operations_struct { void (\*open)(struct vm_area_struct \* area); -void (\*close)(struct vm_area_struct \* area); int (\*fault)(struct -vm_area_struct \*vma, struct vm_fault \*vmf); }; - -The open and close operations must update the GEM object reference -count. Drivers can use the :c:func:`drm_gem_vm_open()` and -:c:func:`drm_gem_vm_close()` helper functions directly as open -and close handlers. - -The fault operation handler is responsible for mapping individual pages -to userspace when a page fault occurs. Depending on the memory -allocation scheme, drivers can allocate pages at fault time, or can -decide to allocate memory for the GEM object at the time the object is -created. - -Drivers that want to map the GEM object upfront instead of handling page -faults can implement their own mmap file operation handler. - -Memory Coherency -^^^^^^^^^^^^^^^^ - -When mapped to the device or used in a command buffer, backing pages for -an object are flushed to memory and marked write combined so as to be -coherent with the GPU. Likewise, if the CPU accesses an object after the -GPU has finished rendering to the object, then the object must be made -coherent with the CPU's view of memory, usually involving GPU cache -flushing of various kinds. This core CPU<->GPU coherency management is -provided by a device-specific ioctl, which evaluates an object's current -domain and performs any necessary flushing or synchronization to put the -object into the desired coherency domain (note that the object may be -busy, i.e. an active render target; in that case, setting the domain -blocks the client and waits for rendering to complete before performing -any necessary flushing operations). - -Command Execution -^^^^^^^^^^^^^^^^^ - -Perhaps the most important GEM function for GPU devices is providing a -command execution interface to clients. Client programs construct -command buffers containing references to previously allocated memory -objects, and then submit them to GEM. At that point, GEM takes care to -bind all the objects into the GTT, execute the buffer, and provide -necessary synchronization between clients accessing the same buffers. -This often involves evicting some objects from the GTT and re-binding -others (a fairly expensive operation), and providing relocation support -which hides fixed GTT offsets from clients. Clients must take care not -to submit command buffers that reference more objects than can fit in -the GTT; otherwise, GEM will reject them and no rendering will occur. -Similarly, if several objects in the buffer require fence registers to -be allocated for correct rendering (e.g. 2D blits on pre-965 chips), -care must be taken not to require more fence registers than are -available to the client. Such resource management should be abstracted -from the client in libdrm. - -GEM Function Reference -~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_gem.c - :export: - -.. kernel-doc:: include/drm/drm_gem.h - :internal: - -VMA Offset Manager -~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c - :doc: vma offset manager - -.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c - :export: - -.. kernel-doc:: include/drm/drm_vma_manager.h - :internal: - -PRIME Buffer Sharing -~~~~~~~~~~~~~~~~~~~~ - -PRIME is the cross device buffer sharing framework in drm, originally -created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME -buffers are dma-buf based file descriptors. - -Overview and Driver Interface -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Similar to GEM global names, PRIME file descriptors are also used to -share buffer objects across processes. They offer additional security: -as file descriptors must be explicitly sent over UNIX domain sockets to -be shared between applications, they can't be guessed like the globally -unique GEM names. - -Drivers that support the PRIME API must set the DRIVER_PRIME bit in the -struct :c:type:`struct drm_driver ` -driver_features field, and implement the prime_handle_to_fd and -prime_fd_to_handle operations. - -int (\*prime_handle_to_fd)(struct drm_device \*dev, struct drm_file -\*file_priv, uint32_t handle, uint32_t flags, int \*prime_fd); int -(\*prime_fd_to_handle)(struct drm_device \*dev, struct drm_file -\*file_priv, int prime_fd, uint32_t \*handle); Those two operations -convert a handle to a PRIME file descriptor and vice versa. Drivers must -use the kernel dma-buf buffer sharing framework to manage the PRIME file -descriptors. Similar to the mode setting API PRIME is agnostic to the -underlying buffer object manager, as long as handles are 32bit unsigned -integers. - -While non-GEM drivers must implement the operations themselves, GEM -drivers must use the :c:func:`drm_gem_prime_handle_to_fd()` and -:c:func:`drm_gem_prime_fd_to_handle()` helper functions. Those -helpers rely on the driver gem_prime_export and gem_prime_import -operations to create a dma-buf instance from a GEM object (dma-buf -exporter role) and to create a GEM object from a dma-buf instance -(dma-buf importer role). - -struct dma_buf \* (\*gem_prime_export)(struct drm_device \*dev, -struct drm_gem_object \*obj, int flags); struct drm_gem_object \* -(\*gem_prime_import)(struct drm_device \*dev, struct dma_buf -\*dma_buf); These two operations are mandatory for GEM drivers that -support PRIME. - -PRIME Helper Functions -^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_prime.c - :doc: PRIME Helpers - -PRIME Function References -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_prime.c - :export: - -DRM MM Range Allocator -~~~~~~~~~~~~~~~~~~~~~~ - -Overview -^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :doc: Overview - -LRU Scan/Eviction Support -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :doc: lru scan roaster - -DRM MM Range Allocator Function References -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :export: - -.. kernel-doc:: include/drm/drm_mm.h - :internal: - -CMA Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c - :doc: cma helpers - -.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c - :export: - -.. kernel-doc:: include/drm/drm_gem_cma_helper.h - :internal: - -Mode Setting ------------- - -Drivers must initialize the mode setting core by calling -:c:func:`drm_mode_config_init()` on the DRM device. The function -initializes the :c:type:`struct drm_device ` -mode_config field and never fails. Once done, mode configuration must -be setup by initializing the following fields. - -- int min_width, min_height; int max_width, max_height; - Minimum and maximum width and height of the frame buffers in pixel - units. - -- struct drm_mode_config_funcs \*funcs; - Mode setting functions. - -Display Modes Function Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_modes.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_modes.c - :export: - -Atomic Mode Setting Function Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :internal: - -Frame Buffer Abstraction -~~~~~~~~~~~~~~~~~~~~~~~~ - -Frame buffers are abstract memory objects that provide a source of -pixels to scanout to a CRTC. Applications explicitly request the -creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls -and receive an opaque handle that can be passed to the KMS CRTC control, -plane configuration and page flip functions. - -Frame buffers rely on the underneath memory manager for low-level memory -operations. When creating a frame buffer applications pass a memory -handle (or a list of memory handles for multi-planar formats) through -the ``drm_mode_fb_cmd2`` argument. For drivers using GEM as their -userspace buffer management interface this would be a GEM handle. -Drivers are however free to use their own backing storage object -handles, e.g. vmwgfx directly exposes special TTM handles to userspace -and so expects TTM handles in the create ioctl and not GEM handles. - -The lifetime of a drm framebuffer is controlled with a reference count, -drivers can grab additional references with -:c:func:`drm_framebuffer_reference()`and drop them again with -:c:func:`drm_framebuffer_unreference()`. For driver-private -framebuffers for which the last reference is never dropped (e.g. for the -fbdev framebuffer when the struct :c:type:`struct drm_framebuffer -` is embedded into the fbdev helper struct) -drivers can manually clean up a framebuffer at module unload time with -:c:func:`drm_framebuffer_unregister_private()`. - -DRM Format Handling -~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_fourcc.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c - :export: - -Dumb Buffer Objects -~~~~~~~~~~~~~~~~~~~ - -The KMS API doesn't standardize backing storage object creation and -leaves it to driver-specific ioctls. Furthermore actually creating a -buffer object even for GEM-based drivers is done through a -driver-specific ioctl - GEM only has a common userspace interface for -sharing and destroying objects. While not an issue for full-fledged -graphics stacks that include device-specific userspace components (in -libdrm for instance), this limit makes DRM-based early boot graphics -unnecessarily complex. - -Dumb objects partly alleviate the problem by providing a standard API to -create dumb buffers suitable for scanout, which can then be used to -create KMS frame buffers. - -To support dumb objects drivers must implement the dumb_create, -dumb_destroy and dumb_map_offset operations. - -- int (\*dumb_create)(struct drm_file \*file_priv, struct - drm_device \*dev, struct drm_mode_create_dumb \*args); - The dumb_create operation creates a driver object (GEM or TTM - handle) suitable for scanout based on the width, height and depth - from the struct :c:type:`struct drm_mode_create_dumb - ` argument. It fills the argument's - handle, pitch and size fields with a handle for the newly created - object and its line pitch and size in bytes. - -- int (\*dumb_destroy)(struct drm_file \*file_priv, struct - drm_device \*dev, uint32_t handle); - The dumb_destroy operation destroys a dumb object created by - dumb_create. - -- int (\*dumb_map_offset)(struct drm_file \*file_priv, struct - drm_device \*dev, uint32_t handle, uint64_t \*offset); - The dumb_map_offset operation associates an mmap fake offset with - the object given by the handle and returns it. Drivers must use the - :c:func:`drm_gem_create_mmap_offset()` function to associate - the fake offset as described in ?. - -Note that dumb objects may not be used for gpu acceleration, as has been -attempted on some ARM embedded platforms. Such drivers really must have -a hardware-specific ioctl to allocate suitable buffer objects. - -Output Polling -~~~~~~~~~~~~~~ - -void (\*output_poll_changed)(struct drm_device \*dev); -This operation notifies the driver that the status of one or more -connectors has changed. Drivers that use the fb helper can just call the -:c:func:`drm_fb_helper_hotplug_event()` function to handle this -operation. - -KMS Initialization and Cleanup ------------------------------- - -A KMS device is abstracted and exposed as a set of planes, CRTCs, -encoders and connectors. KMS drivers must thus create and initialize all -those objects at load time after initializing mode setting. - -CRTCs (:c:type:`struct drm_crtc `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A CRTC is an abstraction representing a part of the chip that contains a -pointer to a scanout buffer. Therefore, the number of CRTCs available -determines how many independent scanout buffers can be active at any -given time. The CRTC structure contains several fields to support this: -a pointer to some video memory (abstracted as a frame buffer object), a -display mode, and an (x, y) offset into the video memory to support -panning or configurations where one piece of video memory spans multiple -CRTCs. - -CRTC Initialization -^^^^^^^^^^^^^^^^^^^ - -A KMS device must create and register at least one struct -:c:type:`struct drm_crtc ` instance. The instance is -allocated and zeroed by the driver, possibly as part of a larger -structure, and registered with a call to :c:func:`drm_crtc_init()` -with a pointer to CRTC functions. - -Planes (:c:type:`struct drm_plane `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A plane represents an image source that can be blended with or overlayed -on top of a CRTC during the scanout process. Planes are associated with -a frame buffer to crop a portion of the image memory (source) and -optionally scale it to a destination size. The result is then blended -with or overlayed on top of a CRTC. - -The DRM core recognizes three types of planes: - -- DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. - Primary planes are the planes operated upon by CRTC modesetting and - flipping operations described in the page_flip hook in - :c:type:`struct drm_crtc_funcs `. -- DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. - Cursor planes are the planes operated upon by the - DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls. -- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor - planes. Some drivers refer to these types of planes as "sprites" - internally. - -For compatibility with legacy userspace, only overlay planes are made -available to userspace by default. Userspace clients may set the -DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate -that they wish to receive a universal plane list containing all plane -types. - -Plane Initialization -^^^^^^^^^^^^^^^^^^^^ - -To create a plane, a KMS drivers allocates and zeroes an instances of -:c:type:`struct drm_plane ` (possibly as part of a -larger structure) and registers it with a call to -:c:func:`drm_universal_plane_init()`. The function takes a -bitmask of the CRTCs that can be associated with the plane, a pointer to -the plane functions, a list of format supported formats, and the type of -plane (primary, cursor, or overlay) being initialized. - -Cursor and overlay planes are optional. All drivers should provide one -primary plane per CRTC (although this requirement may change in the -future); drivers that do not wish to provide special handling for -primary planes may make use of the helper functions described in ? to -create and register a primary plane with standard capabilities. - -Encoders (:c:type:`struct drm_encoder `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -An encoder takes pixel data from a CRTC and converts it to a format -suitable for any attached connectors. On some devices, it may be -possible to have a CRTC send data to more than one encoder. In that -case, both encoders would receive data from the same scanout buffer, -resulting in a "cloned" display configuration across the connectors -attached to each encoder. - -Encoder Initialization -^^^^^^^^^^^^^^^^^^^^^^ - -As for CRTCs, a KMS driver must create, initialize and register at least -one :c:type:`struct drm_encoder ` instance. The -instance is allocated and zeroed by the driver, possibly as part of a -larger structure. - -Drivers must initialize the :c:type:`struct drm_encoder -` possible_crtcs and possible_clones fields before -registering the encoder. Both fields are bitmasks of respectively the -CRTCs that the encoder can be connected to, and sibling encoders -candidate for cloning. - -After being initialized, the encoder must be registered with a call to -:c:func:`drm_encoder_init()`. The function takes a pointer to the -encoder functions and an encoder type. Supported types are - -- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A -- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort -- DRM_MODE_ENCODER_LVDS for display panels -- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, - Component, SCART) -- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays - -Encoders must be attached to a CRTC to be used. DRM drivers leave -encoders unattached at initialization time. Applications (or the fbdev -compatibility layer when implemented) are responsible for attaching the -encoders they want to use to a CRTC. - -Connectors (:c:type:`struct drm_connector `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A connector is the final destination for pixel data on a device, and -usually connects directly to an external display device like a monitor -or laptop panel. A connector can only be attached to one encoder at a -time. The connector is also the structure where information about the -attached display is kept, so it contains fields for display data, EDID -data, DPMS & connection status, and information about modes supported on -the attached displays. - -Connector Initialization -^^^^^^^^^^^^^^^^^^^^^^^^ - -Finally a KMS driver must create, initialize, register and attach at -least one :c:type:`struct drm_connector ` -instance. The instance is created as other KMS objects and initialized -by setting the following fields. - -interlace_allowed - Whether the connector can handle interlaced modes. - -doublescan_allowed - Whether the connector can handle doublescan. - -display_info - Display information is filled from EDID information when a display - is detected. For non hot-pluggable displays such as flat panels in - embedded systems, the driver should initialize the - display_info.width_mm and display_info.height_mm fields with the - physical size of the display. - -polled - Connector polling mode, a combination of - - DRM_CONNECTOR_POLL_HPD - The connector generates hotplug events and doesn't need to be - periodically polled. The CONNECT and DISCONNECT flags must not - be set together with the HPD flag. - - DRM_CONNECTOR_POLL_CONNECT - Periodically poll the connector for connection. - - DRM_CONNECTOR_POLL_DISCONNECT - Periodically poll the connector for disconnection. - - Set to 0 for connectors that don't support connection status - discovery. - -The connector is then registered with a call to -:c:func:`drm_connector_init()` with a pointer to the connector -functions and a connector type, and exposed through sysfs with a call to -:c:func:`drm_connector_register()`. - -Supported connector types are - -- DRM_MODE_CONNECTOR_VGA -- DRM_MODE_CONNECTOR_DVII -- DRM_MODE_CONNECTOR_DVID -- DRM_MODE_CONNECTOR_DVIA -- DRM_MODE_CONNECTOR_Composite -- DRM_MODE_CONNECTOR_SVIDEO -- DRM_MODE_CONNECTOR_LVDS -- DRM_MODE_CONNECTOR_Component -- DRM_MODE_CONNECTOR_9PinDIN -- DRM_MODE_CONNECTOR_DisplayPort -- DRM_MODE_CONNECTOR_HDMIA -- DRM_MODE_CONNECTOR_HDMIB -- DRM_MODE_CONNECTOR_TV -- DRM_MODE_CONNECTOR_eDP -- DRM_MODE_CONNECTOR_VIRTUAL - -Connectors must be attached to an encoder to be used. For devices that -map connectors to encoders 1:1, the connector should be attached at -initialization time with a call to -:c:func:`drm_mode_connector_attach_encoder()`. The driver must -also set the :c:type:`struct drm_connector ` -encoder field to point to the attached encoder. - -Finally, drivers must initialize the connectors state change detection -with a call to :c:func:`drm_kms_helper_poll_init()`. If at least -one connector is pollable but can't generate hotplug interrupts -(indicated by the DRM_CONNECTOR_POLL_CONNECT and -DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will -automatically be queued to periodically poll for changes. Connectors -that can generate hotplug interrupts must be marked with the -DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must -call :c:func:`drm_helper_hpd_irq_event()`. The function will -queue a delayed work to check the state of all connectors, but no -periodic polling will be done. - -Connector Operations -^^^^^^^^^^^^^^^^^^^^ - - **Note** - - Unless otherwise state, all operations are mandatory. - -DPMS -'''' - -void (\*dpms)(struct drm_connector \*connector, int mode); -The DPMS operation sets the power state of a connector. The mode -argument is one of - -- DRM_MODE_DPMS_ON - -- DRM_MODE_DPMS_STANDBY - -- DRM_MODE_DPMS_SUSPEND - -- DRM_MODE_DPMS_OFF - -In all but DPMS_ON mode the encoder to which the connector is attached -should put the display in low-power mode by driving its signals -appropriately. If more than one connector is attached to the encoder -care should be taken not to change the power state of other displays as -a side effect. Low-power mode should be propagated to the encoders and -CRTCs when all related connectors are put in low-power mode. - -Modes -''''' - -int (\*fill_modes)(struct drm_connector \*connector, uint32_t -max_width, uint32_t max_height); -Fill the mode list with all supported modes for the connector. If the -``max_width`` and ``max_height`` arguments are non-zero, the -implementation must ignore all modes wider than ``max_width`` or higher -than ``max_height``. - -The connector must also fill in this operation its display_info -width_mm and height_mm fields with the connected display physical size -in millimeters. The fields should be set to 0 if the value isn't known -or is not applicable (for instance for projector devices). - -Connection Status -''''''''''''''''' - -The connection status is updated through polling or hotplug events when -supported (see ?). The status value is reported to userspace through -ioctls and must not be used inside the driver, as it only gets -initialized by a call to :c:func:`drm_mode_getconnector()` from -userspace. - -enum drm_connector_status (\*detect)(struct drm_connector -\*connector, bool force); -Check to see if anything is attached to the connector. The ``force`` -parameter is set to false whilst polling or to true when checking the -connector due to user request. ``force`` can be used by the driver to -avoid expensive, destructive operations during automated probing. - -Return connector_status_connected if something is connected to the -connector, connector_status_disconnected if nothing is connected and -connector_status_unknown if the connection state isn't known. - -Drivers should only return connector_status_connected if the -connection status has really been probed as connected. Connectors that -can't detect the connection status, or failed connection status probes, -should return connector_status_unknown. - -Cleanup -~~~~~~~ - -The DRM core manages its objects' lifetime. When an object is not needed -anymore the core calls its destroy function, which must clean up and -free every resource allocated for the object. Every -:c:func:`drm_\*_init()` call must be matched with a corresponding -:c:func:`drm_\*_cleanup()` call to cleanup CRTCs -(:c:func:`drm_crtc_cleanup()`), planes -(:c:func:`drm_plane_cleanup()`), encoders -(:c:func:`drm_encoder_cleanup()`) and connectors -(:c:func:`drm_connector_cleanup()`). Furthermore, connectors that -have been added to sysfs must be removed by a call to -:c:func:`drm_connector_unregister()` before calling -:c:func:`drm_connector_cleanup()`. - -Connectors state change detection must be cleanup up with a call to -:c:func:`drm_kms_helper_poll_fini()`. - -Output discovery and initialization example -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - void intel_crt_init(struct drm_device *dev) - { - struct drm_connector *connector; - struct intel_output *intel_output; - - intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) - return; - - connector = &intel_output->base; - drm_connector_init(dev, &intel_output->base, - &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - - drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, - DRM_MODE_ENCODER_DAC); - - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); - - /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return; - } - - intel_output->type = INTEL_OUTPUT_ANALOG; - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); - drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); - - drm_connector_register(connector); - } - -In the example above (taken from the i915 driver), a CRTC, connector and -encoder combination is created. A device-specific i2c bus is also -created for fetching EDID data and performing monitor detection. Once -the process is complete, the new connector is registered with sysfs to -make its properties available to applications. - -KMS API Functions -~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_crtc.c - :export: - -KMS Data Structures -~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_crtc.h - :internal: - -KMS Locking -~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c - :doc: kms locking - -.. kernel-doc:: include/drm/drm_modeset_lock.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c - :export: - -Mode Setting Helper Functions ------------------------------ - -The plane, CRTC, encoder and connector functions provided by the drivers -implement the DRM API. They're called by the DRM core and ioctl handlers -to handle device state changes and configuration request. As -implementing those functions often requires logic not specific to -drivers, mid-layer helper functions are available to avoid duplicating -boilerplate code. - -The DRM core contains one mid-layer implementation. The mid-layer -provides implementations of several plane, CRTC, encoder and connector -functions (called from the top of the mid-layer) that pre-process -requests and call lower-level functions provided by the driver (at the -bottom of the mid-layer). For instance, the -:c:func:`drm_crtc_helper_set_config()` function can be used to -fill the :c:type:`struct drm_crtc_funcs ` -set_config field. When called, it will split the set_config operation -in smaller, simpler operations and call the driver to handle them. - -To use the mid-layer, drivers call -:c:func:`drm_crtc_helper_add()`, -:c:func:`drm_encoder_helper_add()` and -:c:func:`drm_connector_helper_add()` functions to install their -mid-layer bottom operations handlers, and fill the :c:type:`struct -drm_crtc_funcs `, :c:type:`struct -drm_encoder_funcs ` and :c:type:`struct -drm_connector_funcs ` structures with -pointers to the mid-layer top API functions. Installing the mid-layer -bottom operation handlers is best done right after registering the -corresponding KMS object. - -The mid-layer is not split between CRTC, encoder and connector -operations. To use it, a driver must provide bottom functions for all of -the three KMS entities. - -Atomic Modeset Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Overview -^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :doc: overview - -Implementing Asynchronous Atomic Commit -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :doc: implementing nonblocking commit - -Atomic State Reset and Initialization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :doc: atomic state reset and initialization - -.. kernel-doc:: include/drm/drm_atomic_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :export: - -Modeset Helper Reference for Common Vtables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h - :internal: - -.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h - :doc: overview - -Legacy CRTC/Modeset Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c - :doc: overview - -Output Probing Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c - :doc: output probing helper overview - -.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c - :export: - -fbdev Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c - :doc: fbdev helpers - -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c - :export: - -.. kernel-doc:: include/drm/drm_fb_helper.h - :internal: - -Framebuffer CMA Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c - :doc: framebuffer cma helper functions - -.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c - :export: - -Display Port Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c - :doc: dp helpers - -.. kernel-doc:: include/drm/drm_dp_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c - :export: - -Display Port Dual Mode Adaptor Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c - :doc: dp dual mode helpers - -.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c - :export: - -Display Port MST Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c - :doc: dp mst helper - -.. kernel-doc:: include/drm/drm_dp_mst_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c - :export: - -MIPI DSI Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c - :doc: dsi helpers - -.. kernel-doc:: include/drm/drm_mipi_dsi.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c - :export: - -EDID Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_edid.c - :export: - -Rectangle Utilities Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_rect.h - :doc: rect utils - -.. kernel-doc:: include/drm/drm_rect.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_rect.c - :export: - -Flip-work Helper Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_flip_work.h - :doc: flip utils - -.. kernel-doc:: include/drm/drm_flip_work.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_flip_work.c - :export: - -HDMI Infoframes Helper Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Strictly speaking this is not a DRM helper library but generally useable -by any driver interfacing with HDMI outputs like v4l or alsa drivers. -But it nicely fits into the overall topic of mode setting helper -libraries and hence is also included here. - -.. kernel-doc:: include/linux/hdmi.h - :internal: - -.. kernel-doc:: drivers/video/hdmi.c - :export: - -Plane Helper Reference -~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c - :doc: overview - -Tile group -~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_crtc.c - :doc: Tile group - -Bridges -~~~~~~~ - -Overview -^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_bridge.c - :doc: overview - -Default bridge callback sequence -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_bridge.c - :doc: bridge callbacks - -.. kernel-doc:: drivers/gpu/drm/drm_bridge.c - :export: - -Panel Helper Reference -~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_panel.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_panel.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_panel.c - :doc: drm panel - -Simple KMS Helper Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/drm/drm_simple_kms_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c - :doc: overview - -KMS Properties --------------- - -Drivers may need to expose additional parameters to applications than -those described in the previous sections. KMS supports attaching -properties to CRTCs, connectors and planes and offers a userspace API to -list, get and set the property values. - -Properties are identified by a name that uniquely defines the property -purpose, and store an associated value. For all property types except -blob properties the value is a 64-bit unsigned integer. - -KMS differentiates between properties and property instances. Drivers -first create properties and then create and associate individual -instances of those properties to objects. A property can be instantiated -multiple times and associated with different objects. Values are stored -in property instances, and all other property information are stored in -the property and shared between all instances of the property. - -Every property is created with a type that influences how the KMS core -handles the property. Supported property types are - -DRM_MODE_PROP_RANGE - Range properties report their minimum and maximum admissible values. - The KMS core verifies that values set by application fit in that - range. - -DRM_MODE_PROP_ENUM - Enumerated properties take a numerical value that ranges from 0 to - the number of enumerated values defined by the property minus one, - and associate a free-formed string name to each value. Applications - can retrieve the list of defined value-name pairs and use the - numerical value to get and set property instance values. - -DRM_MODE_PROP_BITMASK - Bitmask properties are enumeration properties that additionally - restrict all enumerated values to the 0..63 range. Bitmask property - instance values combine one or more of the enumerated bits defined - by the property. - -DRM_MODE_PROP_BLOB - Blob properties store a binary blob without any format restriction. - The binary blobs are created as KMS standalone objects, and blob - property instance values store the ID of their associated blob - object. - - Blob properties are only used for the connector EDID property and - cannot be created by drivers. - -To create a property drivers call one of the following functions -depending on the property type. All property creation functions take -property flags and name, as well as type-specific arguments. - -- struct drm_property \*drm_property_create_range(struct - drm_device \*dev, int flags, const char \*name, uint64_t min, - uint64_t max); - Create a range property with the given minimum and maximum values. - -- struct drm_property \*drm_property_create_enum(struct drm_device - \*dev, int flags, const char \*name, const struct - drm_prop_enum_list \*props, int num_values); - Create an enumerated property. The ``props`` argument points to an - array of ``num_values`` value-name pairs. - -- struct drm_property \*drm_property_create_bitmask(struct - drm_device \*dev, int flags, const char \*name, const struct - drm_prop_enum_list \*props, int num_values); - Create a bitmask property. The ``props`` argument points to an array - of ``num_values`` value-name pairs. - -Properties can additionally be created as immutable, in which case they -will be read-only for applications but can be modified by the driver. To -create an immutable property drivers must set the -DRM_MODE_PROP_IMMUTABLE flag at property creation time. - -When no array of value-name pairs is readily available at property -creation time for enumerated or range properties, drivers can create the -property using the :c:func:`drm_property_create()` function and -manually add enumeration value-name pairs by calling the -:c:func:`drm_property_add_enum()` function. Care must be taken to -properly specify the property type through the ``flags`` argument. - -After creating properties drivers can attach property instances to CRTC, -connector and plane objects by calling the -:c:func:`drm_object_attach_property()`. The function takes a -pointer to the target object, a pointer to the previously created -property and an initial instance value. - -Existing KMS Properties -~~~~~~~~~~~~~~~~~~~~~~~ - -The following table gives description of drm properties exposed by -various modules/drivers. - -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Owner Module/Drivers | Group | Property Name | Type | Property Values | Object attached | Description/Restrictions | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| DRM | Generic | “rotation” | BITMASK | { 0, "rotate-0" }, { 1, "rotate-90" }, { 2, "rotate-180" }, { 3, "rotate-270" }, { 4, "reflect-x" }, { 5, "reflect-y" } | CRTC, Plane | rotate-(degrees) rotates the image by the specified amount in degrees in counter clockwise direction. reflect-x and reflect-y reflects the image along the specified axis prior to rotation | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “scaling mode” | ENUM | { "None", "Full", "Center", "Full aspect" } | Connector | Supported by: amdgpu, gma500, i915, nouveau and radeon. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Connector | “EDID” | BLOB \| IMMUTABLE | 0 | Connector | Contains id of edid blob ptr object. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “DPMS” | ENUM | { “On”, “Standby”, “Suspend”, “Off” } | Connector | Contains DPMS operation mode value. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “PATH” | BLOB \| IMMUTABLE | 0 | Connector | Contains topology path to a connector. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “TILE” | BLOB \| IMMUTABLE | 0 | Connector | Contains tiling information for a connector. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Connector | CRTC that connector is attached to (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Plane | “type” | ENUM \| IMMUTABLE | { "Overlay", "Primary", "Cursor" } | Plane | Plane type | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_X” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source x coordinate in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_Y” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source y coordinate in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source width in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source height in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_X” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) x coordinate (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_Y” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) y coordinate (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) width (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) height (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “FB_ID” | OBJECT | DRM_MODE_OBJECT_FB | Plane | Scanout framebuffer (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Plane | CRTC that plane is attached to (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| DVI-I | “subconnector” | ENUM | { “Unknown”, “DVI-D”, “DVI-A” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “select subconnector” | ENUM | { “Automatic”, “DVI-D”, “DVI-A” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| TV | “subconnector” | ENUM | { "Unknown", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “select subconnector” | ENUM | { "Automatic", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “left margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “right margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “top margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “bottom margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “brightness” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker reduction” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “overscan” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Virtual GPU | “suggested X” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an X offset for a connector | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “suggested Y” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an Y offset for a connector | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Optional | "aspect ratio" | ENUM | { "None", "4:3", "16:9" } | Connector | TDB | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dirty” | ENUM \| IMMUTABLE | { "Off", "On", "Annotate" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “DEGAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “DEGAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the DEGAMMA_LUT property (the size depends on the underlying hardware). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CTM” | BLOB | 0 | CRTC | DRM property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is an interpreted as a struct drm_color_ctm. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “GAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the gamma lookup table (LUT) mapping pixel data after to the transformation matrix to data sent to the connector. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “GAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the GAMMA_LUT property (the size depends on the underlying hardware). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| i915 | Generic | "Broadcast RGB" | ENUM | { "Automatic", "Full", "Limited 16:235" } | Connector | When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “audio” | ENUM | { "force-dvi", "off", "auto", "on" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| CDV gma-500 | Generic | "Broadcast RGB" | ENUM | { “Full”, “Limited 16:235” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "Broadcast RGB" | ENUM | { “off”, “auto”, “on” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Poulsbo | Generic | “backlight” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| armada | CRTC | "CSC_YUV" | ENUM | { "Auto" , "CCIR601", "CCIR709" } | CRTC | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "CSC_RGB" | ENUM | { "Auto", "Computer system", "Studio" } | CRTC | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Overlay | "colorkey" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_min" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_max" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_val" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_alpha" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_mode" | ENUM | { "disabled", "Y component", "U component" , "V component", "RGB", “R component", "G component", "B component" } | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "brightness" | RANGE | Min=0, Max=256 + 255 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "contrast" | RANGE | Min=0, Max=0x7fff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "saturation" | RANGE | Min=0, Max=0x7fff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| exynos | CRTC | “mode” | ENUM | { "normal", "blank" } | CRTC | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Overlay | “zpos” | RANGE | Min=0, Max=MAX_PLANE-1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| i2c/ch7006_drv | Generic | “scale” | RANGE | Min=0, Max=2 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| TV | “mode” | ENUM | { "PAL", "PAL-M","PAL-N"}, ”PAL-Nc" , "PAL-60", "NTSC-M", "NTSC-J" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| nouveau | NV10 Overlay | "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max=8192-1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max=359 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max=8192-1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “iturbt_709” | RANGE | Min=0, Max=1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Nv04 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Display | “dithering mode” | ENUM | { "auto", "off", "on" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dithering depth” | ENUM | { "auto", "off", "on", "static 2x2", "dynamic 2x2", "temporal" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “underscan” | ENUM | { "auto", "6 bpc", "8 bpc" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “vibrant hue” | RANGE | Min=0, Max=180 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “color vibrance” | RANGE | Min=0, Max=200 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| omap | Generic | “zorder” | RANGE | Min=0, Max=3 | CRTC, Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| qxl | Generic | “hotplug_mode_update" | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| radeon | DVI-I | “coherent” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| DAC enable load detect | “load detection” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| TV Standard | "tv standard" | ENUM | { "ntsc", "pal", "pal-m", "pal-60", "ntsc-j" , "scart-pal", "pal-cn", "secam" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| legacy TMDS PLL detect | "tmds_pll" | ENUM | { "driver", "bios" } | - | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Underscan | "underscan" | ENUM | { "off", "on", "auto" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "underscan hborder" | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "underscan vborder" | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Audio | “audio” | ENUM | { "off", "on", "auto" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| FMT Dithering | “dither” | ENUM | { "off", "on" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| rcar-du | Generic | "alpha" | RANGE | Min=0, Max=255 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "zpos" | RANGE | Min=1, Max=7 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Vertical Blanking ------------------ - -Vertical blanking plays a major role in graphics rendering. To achieve -tear-free display, users must synchronize page flips and/or rendering to -vertical blanking. The DRM API offers ioctls to perform page flips -synchronized to vertical blanking and wait for vertical blanking. - -The DRM core handles most of the vertical blanking management logic, -which involves filtering out spurious interrupts, keeping race-free -blanking counters, coping with counter wrap-around and resets and -keeping use counts. It relies on the driver to generate vertical -blanking interrupts and optionally provide a hardware vertical blanking -counter. Drivers must implement the following operations. - -- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void - (\*disable_vblank) (struct drm_device \*dev, int crtc); - Enable or disable vertical blanking interrupts for the given CRTC. - -- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); - Retrieve the value of the vertical blanking counter for the given - CRTC. If the hardware maintains a vertical blanking counter its value - should be returned. Otherwise drivers can use the - :c:func:`drm_vblank_count()` helper function to handle this - operation. - -Drivers must initialize the vertical blanking handling core with a call -to :c:func:`drm_vblank_init()` in their load operation. - -Vertical blanking interrupts can be enabled by the DRM core or by -drivers themselves (for instance to handle page flipping operations). -The DRM core maintains a vertical blanking use count to ensure that the -interrupts are not disabled while a user still needs them. To increment -the use count, drivers call :c:func:`drm_vblank_get()`. Upon -return vertical blanking interrupts are guaranteed to be enabled. - -To decrement the use count drivers call -:c:func:`drm_vblank_put()`. Only when the use count drops to zero -will the DRM core disable the vertical blanking interrupts after a delay -by scheduling a timer. The delay is accessible through the -vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global -variable and expressed in milliseconds. Its default value is 5000 ms. -Zero means never disable, and a negative value means disable -immediately. Drivers may override the behaviour by setting the -:c:type:`struct drm_device ` -vblank_disable_immediate flag, which when set causes vblank interrupts -to be disabled immediately regardless of the drm_vblank_offdelay -value. The flag should only be set if there's a properly working -hardware vblank counter present. - -When a vertical blanking interrupt occurs drivers only need to call the -:c:func:`drm_handle_vblank()` function to account for the -interrupt. - -Resources allocated by :c:func:`drm_vblank_init()` must be freed -with a call to :c:func:`drm_vblank_cleanup()` in the driver unload -operation handler. - -Vertical Blanking and Interrupt Handling Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_irq.c - :export: - -.. kernel-doc:: include/drm/drmP.h - :functions: drm_crtc_vblank_waitqueue - -Open/Close, File Operations and IOCTLs --------------------------------------- - -Open and Close -~~~~~~~~~~~~~~ - -int (\*firstopen) (struct drm_device \*); void (\*lastclose) (struct -drm_device \*); int (\*open) (struct drm_device \*, struct drm_file -\*); void (\*preclose) (struct drm_device \*, struct drm_file \*); -void (\*postclose) (struct drm_device \*, struct drm_file \*); - Open and close handlers. None of those methods are mandatory. - -The firstopen method is called by the DRM core for legacy UMS (User Mode -Setting) drivers only when an application opens a device that has no -other opened file handle. UMS drivers can implement it to acquire device -resources. KMS drivers can't use the method and must acquire resources -in the load method instead. - -Similarly the lastclose method is called when the last application -holding a file handle opened on the device closes it, for both UMS and -KMS drivers. Additionally, the method is also called at module unload -time or, for hot-pluggable devices, when the device is unplugged. The -firstopen and lastclose calls can thus be unbalanced. - -The open method is called every time the device is opened by an -application. Drivers can allocate per-file private data in this method -and store them in the struct :c:type:`struct drm_file -` driver_priv field. Note that the open method is -called before firstopen. - -The close operation is split into preclose and postclose methods. -Drivers must stop and cleanup all per-file operations in the preclose -method. For instance pending vertical blanking and page flip events must -be cancelled. No per-file operation is allowed on the file handle after -returning from the preclose method. - -Finally the postclose method is called as the last step of the close -operation, right before calling the lastclose method if no other open -file handle exists for the device. Drivers that have allocated per-file -private data in the open method should free it here. - -The lastclose method should restore CRTC and plane properties to default -value, so that a subsequent open of the device will not inherit state -from the previous user. It can also be used to execute delayed power -switching state changes, e.g. in conjunction with the vga_switcheroo -infrastructure (see ?). Beyond that KMS drivers should not do any -further cleanup. Only legacy UMS drivers might need to clean up device -state so that the vga console or an independent fbdev driver could take -over. - -File Operations -~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/drm_fops.c - :doc: file operations - -.. kernel-doc:: drivers/gpu/drm/drm_fops.c - :export: - -IOCTLs -~~~~~~ - -struct drm_ioctl_desc \*ioctls; int num_ioctls; - Driver-specific ioctls descriptors table. - -Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls -descriptors table is indexed by the ioctl number offset from the base -value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize -the table entries. - -:: - - DRM_IOCTL_DEF_DRV(ioctl, func, flags) - -``ioctl`` is the ioctl name. Drivers must define the DRM_##ioctl and -DRM_IOCTL_##ioctl macros to the ioctl number offset from -DRM_COMMAND_BASE and the ioctl number respectively. The first macro is -private to the device while the second must be exposed to userspace in a -public header. - -``func`` is a pointer to the ioctl handler function compatible with the -``drm_ioctl_t`` type. - -:: - - typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -``flags`` is a bitmask combination of the following values. It restricts -how the ioctl is allowed to be called. - -- DRM_AUTH - Only authenticated callers allowed - -- DRM_MASTER - The ioctl can only be called on the master file handle - -- DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed - -- DRM_CONTROL_ALLOW - The ioctl can only be called on a control - device - -- DRM_UNLOCKED - The ioctl handler will be called without locking the - DRM global mutex. This is the enforced default for kms drivers (i.e. - using the DRIVER_MODESET flag) and hence shouldn't be used any more - for new drivers. - -.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c - :export: - -Legacy Support Code -------------------- - -The section very briefly covers some of the old legacy support code -which is only used by old DRM drivers which have done a so-called -shadow-attach to the underlying device instead of registering as a real -driver. This also includes some of the old generic buffer management and -command submission code. Do not use any of this in new and modern -drivers. - -Legacy Suspend/Resume -~~~~~~~~~~~~~~~~~~~~~ - -The DRM core provides some suspend/resume code, but drivers wanting full -suspend/resume support should provide save() and restore() functions. -These are called at suspend, hibernate, or resume time, and should -perform any state save or restore required by your device across suspend -or hibernate states. - -int (\*suspend) (struct drm_device \*, pm_message_t state); int -(\*resume) (struct drm_device \*); -Those are legacy suspend and resume methods which *only* work with the -legacy shadow-attach driver registration functions. New driver should -use the power management interface provided by their bus type (usually -through the :c:type:`struct device_driver ` -dev_pm_ops) and set these methods to NULL. - -Legacy DMA Services -~~~~~~~~~~~~~~~~~~~ - -This should cover how DMA mapping etc. is supported by the core. These -functions are deprecated and should not be used. - -Userland interfaces -=================== - -The DRM core exports several interfaces to applications, generally -intended to be used through corresponding libdrm wrapper functions. In -addition, drivers export device-specific interfaces for use by userspace -drivers & device-aware applications through ioctls and sysfs files. - -External interfaces include: memory mapping, context management, DMA -operations, AGP management, vblank control, fence management, memory -management, and output management. - -Cover generic ioctls and sysfs layout here. We only need high-level -info, since man pages should cover the rest. - -Render nodes ------------- - -DRM core provides multiple character-devices for user-space to use. -Depending on which device is opened, user-space can perform a different -set of operations (mainly ioctls). The primary node is always created -and called card. Additionally, a currently unused control node, -called controlD is also created. The primary node provides all -legacy operations and historically was the only interface used by -userspace. With KMS, the control node was introduced. However, the -planned KMS control interface has never been written and so the control -node stays unused to date. - -With the increased use of offscreen renderers and GPGPU applications, -clients no longer require running compositors or graphics servers to -make use of a GPU. But the DRM API required unprivileged clients to -authenticate to a DRM-Master prior to getting GPU access. To avoid this -step and to grant clients GPU access without authenticating, render -nodes were introduced. Render nodes solely serve render clients, that -is, no modesetting or privileged ioctls can be issued on render nodes. -Only non-global rendering commands are allowed. If a driver supports -render nodes, it must advertise it via the DRIVER_RENDER DRM driver -capability. If not supported, the primary node must be used for render -clients together with the legacy drmAuth authentication procedure. - -If a driver advertises render node support, DRM core will create a -separate render node called renderD. There will be one render node -per device. No ioctls except PRIME-related ioctls will be allowed on -this node. Especially GEM_OPEN will be explicitly prohibited. Render -nodes are designed to avoid the buffer-leaks, which occur if clients -guess the flink names or mmap offsets on the legacy interface. -Additionally to this basic interface, drivers must mark their -driver-dependent render-only ioctls as DRM_RENDER_ALLOW so render -clients can use them. Driver authors must be careful not to allow any -privileged ioctls on render nodes. - -With render nodes, user-space can now control access to the render node -via basic file-system access-modes. A running graphics server which -authenticates clients on the privileged primary/legacy node is no longer -required. Instead, a client can open the render node and is immediately -granted GPU access. Communication between clients (or servers) is done -via PRIME. FLINK from render node to legacy node is not supported. New -clients must not use the insecure FLINK interface. - -Besides dropping all modeset/global ioctls, render nodes also drop the -DRM-Master concept. There is no reason to associate render clients with -a DRM-Master as they are independent of any graphics server. Besides, -they must work without any running master, anyway. Drivers must be able -to run without a master object if they support render nodes. If, on the -other hand, a driver requires shared state between clients which is -visible to user-space and accessible beyond open-file boundaries, they -cannot support render nodes. - -VBlank event handling ---------------------- - -The DRM core exposes two vertical blank related ioctls: - -DRM_IOCTL_WAIT_VBLANK - This takes a struct drm_wait_vblank structure as its argument, and - it is used to block or request a signal when a specified vblank - event occurs. - -DRM_IOCTL_MODESET_CTL - This was only used for user-mode-settind drivers around modesetting - changes to allow the kernel to update the vblank interrupt after - mode setting, since on many devices the vertical blank counter is - reset to 0 at some point during modeset. Modern drivers should not - call this any more since with kernel mode setting it is a no-op. - -This second part of the GPU Driver Developer's Guide documents driver -code, implementation details and also all the driver-specific userspace -interfaces. Especially since all hardware-acceleration interfaces to -userspace are driver specific for efficiency and other reasons these -interfaces can be rather substantial. Hence every driver has its own -chapter. - -drm/i915 Intel GFX Driver -========================= - -The drm/i915 driver supports all (with the exception of some very early -models) integrated GFX chipsets with both Intel display and rendering -blocks. This excludes a set of SoC platforms with an SGX rendering unit, -those have basic support through the gma500 drm driver. - -Core Driver Infrastructure --------------------------- - -This section covers core driver infrastructure used by both the display -and the GEM parts of the driver. - -Runtime Power Management -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c - :doc: runtime pm - -.. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c - :internal: - -.. kernel-doc:: drivers/gpu/drm/i915/intel_uncore.c - :internal: - -Interrupt Handling -~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c - :doc: interrupt handling - -.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c - :functions: intel_irq_init intel_irq_init_hw intel_hpd_init - -.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c - :functions: intel_runtime_pm_disable_interrupts - -.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c - :functions: intel_runtime_pm_enable_interrupts - -Intel GVT-g Guest Support(vGPU) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c - :doc: Intel GVT-g guest support - -.. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c - :internal: - -Display Hardware Handling -------------------------- - -This section covers everything related to the display hardware including -the mode setting infrastructure, plane, sprite and cursor handling and -display, output probing and related topics. - -Mode Setting Infrastructure -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The i915 driver is thus far the only DRM driver which doesn't use the -common DRM helper code to implement mode setting sequences. Thus it has -its own tailor-made infrastructure for executing a display configuration -change. - -Frontbuffer Tracking -~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c - :doc: frontbuffer tracking - -.. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c - :internal: - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem.c - :functions: i915_gem_track_fb - -Display FIFO Underrun Reporting -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c - :doc: fifo underrun handling - -.. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c - :internal: - -Plane Configuration -~~~~~~~~~~~~~~~~~~~ - -This section covers plane configuration and composition with the primary -plane, sprites, cursors and overlays. This includes the infrastructure -to do atomic vsync'ed updates of all this state and also tightly coupled -topics like watermark setup and computation, framebuffer compression and -panel self refresh. - -Atomic Plane Helpers -~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c - :doc: atomic plane helpers - -.. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c - :internal: - -Output Probing -~~~~~~~~~~~~~~ - -This section covers output probing and related infrastructure like the -hotplug interrupt storm detection and mitigation code. Note that the -i915 driver still uses most of the common DRM helper code for output -probing, so those sections fully apply. - -Hotplug -~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c - :doc: Hotplug - -.. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c - :internal: - -High Definition Audio -~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c - :doc: High Definition Audio over HDMI and Display Port - -.. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c - :internal: - -.. kernel-doc:: include/drm/i915_component.h - :internal: - -Panel Self Refresh PSR (PSR/SRD) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c - :doc: Panel Self Refresh (PSR/SRD) - -.. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c - :internal: - -Frame Buffer Compression (FBC) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c - :doc: Frame Buffer Compression (FBC) - -.. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c - :internal: - -Display Refresh Rate Switching (DRRS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :doc: Display Refresh Rate Switching (DRRS) - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :functions: intel_dp_set_drrs_state - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :functions: intel_edp_drrs_enable - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :functions: intel_edp_drrs_disable - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :functions: intel_edp_drrs_invalidate - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :functions: intel_edp_drrs_flush - -.. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c - :functions: intel_dp_drrs_init - -DPIO -~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h - :doc: DPIO - -CSR firmware support for DMC -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c - :doc: csr support for dmc - -.. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c - :internal: - -Video BIOS Table (VBT) -~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c - :doc: Video BIOS Table (VBT) - -.. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c - :internal: - -.. kernel-doc:: drivers/gpu/drm/i915/intel_vbt_defs.h - :internal: - -Memory Management and Command Submission ----------------------------------------- - -This sections covers all things related to the GEM implementation in the -i915 driver. - -Batchbuffer Parsing -~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c - :doc: batch buffer command parser - -.. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c - :internal: - -Batchbuffer Pools -~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c - :doc: batch pool - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c - :internal: - -Logical Rings, Logical Ring Contexts and Execlists -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c - :doc: Logical Rings, Logical Ring Contexts and Execlists - -.. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c - :internal: - -Global GTT views -~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c - :doc: Global GTT views - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c - :internal: - -GTT Fences and Swizzling -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c - :internal: - -Global GTT Fence Handling -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c - :doc: fence register handling - -Hardware Tiling and Swizzling Details -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c - :doc: tiling swizzling details - -Object Tiling IOCTLs -~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c - :internal: - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c - :doc: buffer object tiling - -Buffer Object Eviction -~~~~~~~~~~~~~~~~~~~~~~ - -This section documents the interface functions for evicting buffer -objects to make space available in the virtual gpu address spaces. Note -that this is mostly orthogonal to shrinking buffer objects caches, which -has the goal to make main memory (shared with the gpu through the -unified memory architecture) available. - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_evict.c - :internal: - -Buffer Object Memory Shrinking -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section documents the interface function for shrinking memory usage -of buffer object caches. Shrinking is used to make main memory -available. Note that this is mostly orthogonal to evicting buffer -objects, which has the goal to make space in gpu virtual address spaces. - -.. kernel-doc:: drivers/gpu/drm/i915/i915_gem_shrinker.c - :internal: - -GuC ---- - -GuC-specific firmware loader -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c - :doc: GuC-specific firmware loader - -.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c - :internal: - -GuC-based command submission -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c - :doc: GuC-based command submission - -.. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c - :internal: - -GuC Firmware Layout -~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fwif.h - :doc: GuC Firmware Layout - -Tracing -------- - -This sections covers all things related to the tracepoints implemented -in the i915 driver. - -i915_ppgtt_create and i915_ppgtt_release -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h - :doc: i915_ppgtt_create and i915_ppgtt_release tracepoints - -i915_context_create and i915_context_free -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h - :doc: i915_context_create and i915_context_free tracepoints - -switch_mm -~~~~~~~~~~ - -.. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h - :doc: switch_mm tracepoint - -.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/drm/i915/i915_irq.c - -.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c - :doc: Overview - -Modes of Use -============ - -Manual switching and manual power control ------------------------------------------ - -.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c - :doc: Manual switching and manual power control - -Driver power control --------------------- - -.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c - :doc: Driver power control - -API -=== - -Public functions ----------------- - -.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c - :export: - -Public structures ------------------ - -.. kernel-doc:: include/linux/vga_switcheroo.h - :functions: vga_switcheroo_handler - -.. kernel-doc:: include/linux/vga_switcheroo.h - :functions: vga_switcheroo_client_ops - -Public constants ----------------- - -.. kernel-doc:: include/linux/vga_switcheroo.h - :functions: vga_switcheroo_handler_flags_t - -.. kernel-doc:: include/linux/vga_switcheroo.h - :functions: vga_switcheroo_client_id - -.. kernel-doc:: include/linux/vga_switcheroo.h - :functions: vga_switcheroo_state - -Private structures ------------------- - -.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c - :functions: vgasr_priv - -.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c - :functions: vga_switcheroo_client - -Handlers -======== - -apple-gmux Handler ------------------- - -.. kernel-doc:: drivers/platform/x86/apple-gmux.c - :doc: Overview - -.. kernel-doc:: drivers/platform/x86/apple-gmux.c - :doc: Interrupt - -Graphics mux -~~~~~~~~~~~~ - -.. kernel-doc:: drivers/platform/x86/apple-gmux.c - :doc: Graphics mux - -Power control -~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/platform/x86/apple-gmux.c - :doc: Power control - -Backlight control -~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: drivers/platform/x86/apple-gmux.c - :doc: Backlight control - -Public functions -~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/linux/apple-gmux.h - :internal: - -.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/vga/vga_switcheroo.c - -.. WARNING: DOCPROC directive not supported: !Cinclude/linux/vga_switcheroo.h - -.. WARNING: DOCPROC directive not supported: !Cdrivers/platform/x86/apple-gmux.c + introduction + drm-internals + drm-uapi + i915 + vga-switcheroo diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst new file mode 100644 index 000000000000..cf35c4fe992f --- /dev/null +++ b/Documentation/gpu/introduction.rst @@ -0,0 +1,50 @@ +Introduction +============ + +The Linux DRM layer contains code intended to support the needs of +complex graphics devices, usually containing programmable pipelines well +suited to 3D graphics acceleration. Graphics drivers in the kernel may +make use of DRM functions to make tasks like memory management, +interrupt handling and DMA easier, and provide a uniform interface to +applications. + +A note on versions: this guide covers features found in the DRM tree, +including the TTM memory manager, output configuration and mode setting, +and the new vblank internals, in addition to all the regular features +found in current kernels. + +[Insert diagram of typical DRM stack here] + +Style Guidelines +---------------- + +For consistency this documentation uses American English. Abbreviations +are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so +on. To aid in reading, documentations make full use of the markup +characters kerneldoc provides: @parameter for function parameters, +@member for structure members, &structure to reference structures and +function() for functions. These all get automatically hyperlinked if +kerneldoc for the referenced objects exists. When referencing entries in +function vtables please use ->vfunc(). Note that kerneldoc does not +support referencing struct members directly, so please add a reference +to the vtable struct somewhere in the same paragraph or at least +section. + +Except in special situations (to separate locked from unlocked variants) +locking requirements for functions aren't documented in the kerneldoc. +Instead locking should be check at runtime using e.g. +``WARN_ON(!mutex_is_locked(...));``. Since it's much easier to ignore +documentation than runtime noise this provides more value. And on top of +that runtime checks do need to be updated when the locking rules change, +increasing the chances that they're correct. Within the documentation +the locking rules should be explained in the relevant structures: Either +in the comment for the lock explaining what it protects, or data fields +need a note about which lock protects them, or both. + +Functions which have a non-\ ``void`` return value should have a section +called "Returns" explaining the expected return values in different +cases and their meanings. Currently there's no consensus whether that +section name should be all upper-case or not, and whether it should end +in a colon or not. Go with the file-local style. Other common section +names are "Notes" with information for dangerous or tricky corner cases, +and "FIXME" where the interface could be cleaned up. diff --git a/Documentation/gpu/vga-switcheroo.rst b/Documentation/gpu/vga-switcheroo.rst new file mode 100644 index 000000000000..327d930a2229 --- /dev/null +++ b/Documentation/gpu/vga-switcheroo.rst @@ -0,0 +1,102 @@ +============== +VGA Switcheroo +============== + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :doc: Overview + +Modes of Use +============ + +Manual switching and manual power control +----------------------------------------- + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :doc: Manual switching and manual power control + +Driver power control +-------------------- + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :doc: Driver power control + +API +=== + +Public functions +---------------- + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :export: + +Public structures +----------------- + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_handler + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_client_ops + +Public constants +---------------- + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_handler_flags_t + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_client_id + +.. kernel-doc:: include/linux/vga_switcheroo.h + :functions: vga_switcheroo_state + +Private structures +------------------ + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :functions: vgasr_priv + +.. kernel-doc:: drivers/gpu/vga/vga_switcheroo.c + :functions: vga_switcheroo_client + +Handlers +======== + +apple-gmux Handler +------------------ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Overview + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Interrupt + +Graphics mux +~~~~~~~~~~~~ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Graphics mux + +Power control +~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Power control + +Backlight control +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/platform/x86/apple-gmux.c + :doc: Backlight control + +Public functions +~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/linux/apple-gmux.h + :internal: + +.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/vga/vga_switcheroo.c + +.. WARNING: DOCPROC directive not supported: !Cinclude/linux/vga_switcheroo.h + +.. WARNING: DOCPROC directive not supported: !Cdrivers/platform/x86/apple-gmux.c -- cgit v1.3-14-g43fede From 22554020409f6febcce2790380e46cd483ae04bb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Jun 2016 14:49:00 +0300 Subject: Documentation/gpu: use recommended order of heading markers While splitting the document up, the headings "shifted" from what pandoc generated. Use the following order for headings for consistency: ============== Document title ============== First ===== Second ------ Third ~~~~~ Leave the lower level headings as they are; I think those are less important. Although RST doesn't mandate a specific order ("Rather than imposing a fixed number and order of section title adornment styles, the order enforced will be the order as encountered."), having the higher levels the same overall makes it easier to follow the documents. [I'm sort of kind of writing the recommendation for docs-next in the mean time, but this order seems sensible, and is what I'm proposing.] Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/126f42734defac6cbb8496a481d58db7b38461dd.1466506505.git.jani.nikula@intel.com --- Documentation/gpu/drm-internals.rst | 127 ++++++++++++++++++------------------ Documentation/gpu/drm-uapi.rst | 5 +- Documentation/gpu/i915.rst | 81 +++++++++++------------ Documentation/gpu/introduction.rst | 3 +- 4 files changed, 110 insertions(+), 106 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 8b8257891396..ee01a4fbd657 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -1,3 +1,4 @@ +============= DRM Internals ============= @@ -18,7 +19,7 @@ management, command submission & fencing, suspend/resume support, and DMA services. Driver Initialization ---------------------- +===================== At the core of every DRM driver is a :c:type:`struct drm_driver ` structure. Drivers typically statically initialize @@ -36,7 +37,7 @@ then describe individual operations in details as they get used in later sections. Driver Information -~~~~~~~~~~~~~~~~~~ +------------------ Driver Features ^^^^^^^^^^^^^^^ @@ -131,7 +132,7 @@ kernel log at initialization time and passes it to userspace through the DRM_IOCTL_VERSION ioctl. Device Instance and Driver Handling -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_drv.c :doc: driver instance overview @@ -140,7 +141,7 @@ Device Instance and Driver Handling :export: Driver Load -~~~~~~~~~~~ +----------- IRQ Registration ^^^^^^^^^^^^^^^^ @@ -221,7 +222,7 @@ other BARs, so leaving it mapped could cause undesired behaviour like hangs or memory corruption. Bus-specific Device Registration and PCI Support -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------ A number of functions are provided to help with device registration. The functions deal with PCI and platform devices respectively and are only @@ -236,7 +237,7 @@ drivers. :export: Memory management ------------------ +================= Modern Linux systems require large amount of graphics memory to store frame buffers, textures, vertices and other graphics-related data. Given @@ -262,7 +263,7 @@ TTM, but has no video RAM management capabilities and is thus limited to UMA devices. The Translation Table Manager (TTM) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------- TTM design background and information belongs here. @@ -313,7 +314,7 @@ object, ttm_global_item_ref() is used to create an initial reference count for the TTM, which will call your initialization function. The Graphics Execution Manager (GEM) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------ The GEM design approach has resulted in a memory manager that doesn't provide full coverage of all (or even all common) use cases in its @@ -576,7 +577,7 @@ available to the client. Such resource management should be abstracted from the client in libdrm. GEM Function Reference -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- .. kernel-doc:: drivers/gpu/drm/drm_gem.c :export: @@ -585,7 +586,7 @@ GEM Function Reference :internal: VMA Offset Manager -~~~~~~~~~~~~~~~~~~ +------------------ .. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c :doc: vma offset manager @@ -597,7 +598,7 @@ VMA Offset Manager :internal: PRIME Buffer Sharing -~~~~~~~~~~~~~~~~~~~~ +-------------------- PRIME is the cross device buffer sharing framework in drm, originally created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME @@ -648,13 +649,13 @@ PRIME Helper Functions :doc: PRIME Helpers PRIME Function References -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- .. kernel-doc:: drivers/gpu/drm/drm_prime.c :export: DRM MM Range Allocator -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- Overview ^^^^^^^^ @@ -669,7 +670,7 @@ LRU Scan/Eviction Support :doc: lru scan roaster DRM MM Range Allocator Function References -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------ .. kernel-doc:: drivers/gpu/drm/drm_mm.c :export: @@ -678,7 +679,7 @@ DRM MM Range Allocator Function References :internal: CMA Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c :doc: cma helpers @@ -690,7 +691,7 @@ CMA Helper Functions Reference :internal: Mode Setting ------------- +============ Drivers must initialize the mode setting core by calling :c:func:`drm_mode_config_init()` on the DRM device. The function @@ -706,7 +707,7 @@ be setup by initializing the following fields. Mode setting functions. Display Modes Function Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- .. kernel-doc:: include/drm/drm_modes.h :internal: @@ -715,7 +716,7 @@ Display Modes Function Reference :export: Atomic Mode Setting Function Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :export: @@ -724,7 +725,7 @@ Atomic Mode Setting Function Reference :internal: Frame Buffer Abstraction -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ Frame buffers are abstract memory objects that provide a source of pixels to scanout to a CRTC. Applications explicitly request the @@ -752,7 +753,7 @@ drivers can manually clean up a framebuffer at module unload time with :c:func:`drm_framebuffer_unregister_private()`. DRM Format Handling -~~~~~~~~~~~~~~~~~~~ +------------------- .. kernel-doc:: include/drm/drm_fourcc.h :internal: @@ -761,7 +762,7 @@ DRM Format Handling :export: Dumb Buffer Objects -~~~~~~~~~~~~~~~~~~~ +------------------- The KMS API doesn't standardize backing storage object creation and leaves it to driver-specific ioctls. Furthermore actually creating a @@ -805,7 +806,7 @@ attempted on some ARM embedded platforms. Such drivers really must have a hardware-specific ioctl to allocate suitable buffer objects. Output Polling -~~~~~~~~~~~~~~ +-------------- void (\*output_poll_changed)(struct drm_device \*dev); This operation notifies the driver that the status of one or more @@ -814,14 +815,14 @@ connectors has changed. Drivers that use the fb helper can just call the operation. KMS Initialization and Cleanup ------------------------------- +============================== A KMS device is abstracted and exposed as a set of planes, CRTCs, encoders and connectors. KMS drivers must thus create and initialize all those objects at load time after initializing mode setting. CRTCs (:c:type:`struct drm_crtc `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------------------- A CRTC is an abstraction representing a part of the chip that contains a pointer to a scanout buffer. Therefore, the number of CRTCs available @@ -842,7 +843,7 @@ structure, and registered with a call to :c:func:`drm_crtc_init()` with a pointer to CRTC functions. Planes (:c:type:`struct drm_plane `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------------- A plane represents an image source that can be blended with or overlayed on top of a CRTC during the scanout process. Planes are associated with @@ -887,7 +888,7 @@ primary planes may make use of the helper functions described in ? to create and register a primary plane with standard capabilities. Encoders (:c:type:`struct drm_encoder `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------------------- An encoder takes pixel data from a CRTC and converts it to a format suitable for any attached connectors. On some devices, it may be @@ -927,7 +928,7 @@ compatibility layer when implemented) are responsible for attaching the encoders they want to use to a CRTC. Connectors (:c:type:`struct drm_connector `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------------------------- A connector is the final destination for pixel data on a device, and usually connects directly to an external display device like a monitor @@ -1087,7 +1088,7 @@ can't detect the connection status, or failed connection status probes, should return connector_status_unknown. Cleanup -~~~~~~~ +------- The DRM core manages its objects' lifetime. When an object is not needed anymore the core calls its destroy function, which must clean up and @@ -1106,7 +1107,7 @@ Connectors state change detection must be cleanup up with a call to :c:func:`drm_kms_helper_poll_fini()`. Output discovery and initialization example -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------- :: @@ -1154,19 +1155,19 @@ the process is complete, the new connector is registered with sysfs to make its properties available to applications. KMS API Functions -~~~~~~~~~~~~~~~~~ +----------------- .. kernel-doc:: drivers/gpu/drm/drm_crtc.c :export: KMS Data Structures -~~~~~~~~~~~~~~~~~~~ +------------------- .. kernel-doc:: include/drm/drm_crtc.h :internal: KMS Locking -~~~~~~~~~~~ +----------- .. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c :doc: kms locking @@ -1178,7 +1179,7 @@ KMS Locking :export: Mode Setting Helper Functions ------------------------------ +============================= The plane, CRTC, encoder and connector functions provided by the drivers implement the DRM API. They're called by the DRM core and ioctl handlers @@ -1214,7 +1215,7 @@ operations. To use it, a driver must provide bottom functions for all of the three KMS entities. Atomic Modeset Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------- Overview ^^^^^^^^ @@ -1241,7 +1242,7 @@ Atomic State Reset and Initialization :export: Modeset Helper Reference for Common Vtables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------- .. kernel-doc:: include/drm/drm_modeset_helper_vtables.h :internal: @@ -1250,7 +1251,7 @@ Modeset Helper Reference for Common Vtables :doc: overview Legacy CRTC/Modeset Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c :export: @@ -1259,7 +1260,7 @@ Legacy CRTC/Modeset Helper Functions Reference :doc: overview Output Probing Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c :doc: output probing helper overview @@ -1268,7 +1269,7 @@ Output Probing Helper Functions Reference :export: fbdev Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :doc: fbdev helpers @@ -1280,7 +1281,7 @@ fbdev Helper Functions Reference :internal: Framebuffer CMA Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------ .. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c :doc: framebuffer cma helper functions @@ -1289,7 +1290,7 @@ Framebuffer CMA Helper Functions Reference :export: Display Port Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c :doc: dp helpers @@ -1301,7 +1302,7 @@ Display Port Helper Functions Reference :export: Display Port Dual Mode Adaptor Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c :doc: dp dual mode helpers @@ -1313,7 +1314,7 @@ Display Port Dual Mode Adaptor Helper Functions Reference :export: Display Port MST Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c :doc: dp mst helper @@ -1325,7 +1326,7 @@ Display Port MST Helper Functions Reference :export: MIPI DSI Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c :doc: dsi helpers @@ -1337,13 +1338,13 @@ MIPI DSI Helper Functions Reference :export: EDID Helper Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_edid.c :export: Rectangle Utilities Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- .. kernel-doc:: include/drm/drm_rect.h :doc: rect utils @@ -1355,7 +1356,7 @@ Rectangle Utilities Reference :export: Flip-work Helper Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------- .. kernel-doc:: include/drm/drm_flip_work.h :doc: flip utils @@ -1367,7 +1368,7 @@ Flip-work Helper Reference :export: HDMI Infoframes Helper Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- Strictly speaking this is not a DRM helper library but generally useable by any driver interfacing with HDMI outputs like v4l or alsa drivers. @@ -1381,7 +1382,7 @@ libraries and hence is also included here. :export: Plane Helper Reference -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- .. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c :export: @@ -1390,13 +1391,13 @@ Plane Helper Reference :doc: overview Tile group -~~~~~~~~~~ +---------- .. kernel-doc:: drivers/gpu/drm/drm_crtc.c :doc: Tile group Bridges -~~~~~~~ +------- Overview ^^^^^^^^ @@ -1414,7 +1415,7 @@ Default bridge callback sequence :export: Panel Helper Reference -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- .. kernel-doc:: include/drm/drm_panel.h :internal: @@ -1426,7 +1427,7 @@ Panel Helper Reference :doc: drm panel Simple KMS Helper Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- .. kernel-doc:: include/drm/drm_simple_kms_helper.h :internal: @@ -1438,7 +1439,7 @@ Simple KMS Helper Reference :doc: overview KMS Properties --------------- +============== Drivers may need to expose additional parameters to applications than those described in the previous sections. KMS supports attaching @@ -1526,7 +1527,7 @@ pointer to the target object, a pointer to the previously created property and an initial instance value. Existing KMS Properties -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- The following table gives description of drm properties exposed by various modules/drivers. @@ -1790,7 +1791,7 @@ various modules/drivers. +-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ Vertical Blanking ------------------ +================= Vertical blanking plays a major role in graphics rendering. To achieve tear-free display, users must synchronize page flips and/or rendering to @@ -1848,7 +1849,7 @@ with a call to :c:func:`drm_vblank_cleanup()` in the driver unload operation handler. Vertical Blanking and Interrupt Handling Functions Reference -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------------------ .. kernel-doc:: drivers/gpu/drm/drm_irq.c :export: @@ -1857,10 +1858,10 @@ Vertical Blanking and Interrupt Handling Functions Reference :functions: drm_crtc_vblank_waitqueue Open/Close, File Operations and IOCTLs --------------------------------------- +====================================== Open and Close -~~~~~~~~~~~~~~ +-------------- int (\*firstopen) (struct drm_device \*); void (\*lastclose) (struct drm_device \*); int (\*open) (struct drm_device \*, struct drm_file @@ -1907,7 +1908,7 @@ state so that the vga console or an independent fbdev driver could take over. File Operations -~~~~~~~~~~~~~~~ +--------------- .. kernel-doc:: drivers/gpu/drm/drm_fops.c :doc: file operations @@ -1916,7 +1917,7 @@ File Operations :export: IOCTLs -~~~~~~ +------ struct drm_ioctl_desc \*ioctls; int num_ioctls; Driver-specific ioctls descriptors table. @@ -1965,7 +1966,7 @@ how the ioctl is allowed to be called. :export: Legacy Support Code -------------------- +=================== The section very briefly covers some of the old legacy support code which is only used by old DRM drivers which have done a so-called @@ -1975,7 +1976,7 @@ command submission code. Do not use any of this in new and modern drivers. Legacy Suspend/Resume -~~~~~~~~~~~~~~~~~~~~~ +--------------------- The DRM core provides some suspend/resume code, but drivers wanting full suspend/resume support should provide save() and restore() functions. @@ -1992,7 +1993,7 @@ through the :c:type:`struct device_driver ` dev_pm_ops) and set these methods to NULL. Legacy DMA Services -~~~~~~~~~~~~~~~~~~~ +------------------- This should cover how DMA mapping etc. is supported by the core. These functions are deprecated and should not be used. diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 3b667b1992e5..6da1e77e55fa 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -1,3 +1,4 @@ +=================== Userland interfaces =================== @@ -14,7 +15,7 @@ Cover generic ioctls and sysfs layout here. We only need high-level info, since man pages should cover the rest. Render nodes ------------- +============ DRM core provides multiple character-devices for user-space to use. Depending on which device is opened, user-space can perform a different @@ -67,7 +68,7 @@ visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes. VBlank event handling ---------------------- +===================== The DRM core exposes two vertical blank related ioctls: diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 9c6732123c3c..2fe5952e90f1 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -1,5 +1,6 @@ -drm/i915 Intel GFX Driver -========================= +=========================== + drm/i915 Intel GFX Driver +=========================== The drm/i915 driver supports all (with the exception of some very early models) integrated GFX chipsets with both Intel display and rendering @@ -7,13 +8,13 @@ blocks. This excludes a set of SoC platforms with an SGX rendering unit, those have basic support through the gma500 drm driver. Core Driver Infrastructure --------------------------- +========================== This section covers core driver infrastructure used by both the display and the GEM parts of the driver. Runtime Power Management -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ .. kernel-doc:: drivers/gpu/drm/i915/intel_runtime_pm.c :doc: runtime pm @@ -25,7 +26,7 @@ Runtime Power Management :internal: Interrupt Handling -~~~~~~~~~~~~~~~~~~ +------------------ .. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c :doc: interrupt handling @@ -40,7 +41,7 @@ Interrupt Handling :functions: intel_runtime_pm_enable_interrupts Intel GVT-g Guest Support(vGPU) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_vgpu.c :doc: Intel GVT-g guest support @@ -49,14 +50,14 @@ Intel GVT-g Guest Support(vGPU) :internal: Display Hardware Handling -------------------------- +========================= This section covers everything related to the display hardware including the mode setting infrastructure, plane, sprite and cursor handling and display, output probing and related topics. Mode Setting Infrastructure -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- The i915 driver is thus far the only DRM driver which doesn't use the common DRM helper code to implement mode setting sequences. Thus it has @@ -64,7 +65,7 @@ its own tailor-made infrastructure for executing a display configuration change. Frontbuffer Tracking -~~~~~~~~~~~~~~~~~~~~ +-------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_frontbuffer.c :doc: frontbuffer tracking @@ -76,7 +77,7 @@ Frontbuffer Tracking :functions: i915_gem_track_fb Display FIFO Underrun Reporting -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_fifo_underrun.c :doc: fifo underrun handling @@ -85,7 +86,7 @@ Display FIFO Underrun Reporting :internal: Plane Configuration -~~~~~~~~~~~~~~~~~~~ +------------------- This section covers plane configuration and composition with the primary plane, sprites, cursors and overlays. This includes the infrastructure @@ -94,7 +95,7 @@ topics like watermark setup and computation, framebuffer compression and panel self refresh. Atomic Plane Helpers -~~~~~~~~~~~~~~~~~~~~ +-------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_atomic_plane.c :doc: atomic plane helpers @@ -103,7 +104,7 @@ Atomic Plane Helpers :internal: Output Probing -~~~~~~~~~~~~~~ +-------------- This section covers output probing and related infrastructure like the hotplug interrupt storm detection and mitigation code. Note that the @@ -111,7 +112,7 @@ i915 driver still uses most of the common DRM helper code for output probing, so those sections fully apply. Hotplug -~~~~~~~ +------- .. kernel-doc:: drivers/gpu/drm/i915/intel_hotplug.c :doc: Hotplug @@ -120,7 +121,7 @@ Hotplug :internal: High Definition Audio -~~~~~~~~~~~~~~~~~~~~~ +--------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c :doc: High Definition Audio over HDMI and Display Port @@ -132,7 +133,7 @@ High Definition Audio :internal: Panel Self Refresh PSR (PSR/SRD) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_psr.c :doc: Panel Self Refresh (PSR/SRD) @@ -141,7 +142,7 @@ Panel Self Refresh PSR (PSR/SRD) :internal: Frame Buffer Compression (FBC) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ .. kernel-doc:: drivers/gpu/drm/i915/intel_fbc.c :doc: Frame Buffer Compression (FBC) @@ -150,7 +151,7 @@ Frame Buffer Compression (FBC) :internal: Display Refresh Rate Switching (DRRS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_dp.c :doc: Display Refresh Rate Switching (DRRS) @@ -174,13 +175,13 @@ Display Refresh Rate Switching (DRRS) :functions: intel_dp_drrs_init DPIO -~~~~ +---- .. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h :doc: DPIO CSR firmware support for DMC -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_csr.c :doc: csr support for dmc @@ -189,7 +190,7 @@ CSR firmware support for DMC :internal: Video BIOS Table (VBT) -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_bios.c :doc: Video BIOS Table (VBT) @@ -201,13 +202,13 @@ Video BIOS Table (VBT) :internal: Memory Management and Command Submission ----------------------------------------- +======================================== This sections covers all things related to the GEM implementation in the i915 driver. Batchbuffer Parsing -~~~~~~~~~~~~~~~~~~~ +------------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_cmd_parser.c :doc: batch buffer command parser @@ -216,7 +217,7 @@ Batchbuffer Parsing :internal: Batchbuffer Pools -~~~~~~~~~~~~~~~~~ +----------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_gem_batch_pool.c :doc: batch pool @@ -225,7 +226,7 @@ Batchbuffer Pools :internal: Logical Rings, Logical Ring Contexts and Execlists -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_lrc.c :doc: Logical Rings, Logical Ring Contexts and Execlists @@ -234,7 +235,7 @@ Logical Rings, Logical Ring Contexts and Execlists :internal: Global GTT views -~~~~~~~~~~~~~~~~ +---------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_gem_gtt.c :doc: Global GTT views @@ -243,25 +244,25 @@ Global GTT views :internal: GTT Fences and Swizzling -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ .. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c :internal: Global GTT Fence Handling -^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~ .. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c :doc: fence register handling Hardware Tiling and Swizzling Details -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. kernel-doc:: drivers/gpu/drm/i915/i915_gem_fence.c :doc: tiling swizzling details Object Tiling IOCTLs -~~~~~~~~~~~~~~~~~~~~ +-------------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_gem_tiling.c :internal: @@ -270,7 +271,7 @@ Object Tiling IOCTLs :doc: buffer object tiling Buffer Object Eviction -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- This section documents the interface functions for evicting buffer objects to make space available in the virtual gpu address spaces. Note @@ -282,7 +283,7 @@ unified memory architecture) available. :internal: Buffer Object Memory Shrinking -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ This section documents the interface function for shrinking memory usage of buffer object caches. Shrinking is used to make main memory @@ -293,10 +294,10 @@ objects, which has the goal to make space in gpu virtual address spaces. :internal: GuC ---- +=== GuC-specific firmware loader -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c :doc: GuC-specific firmware loader @@ -305,7 +306,7 @@ GuC-specific firmware loader :internal: GuC-based command submission -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c :doc: GuC-based command submission @@ -314,31 +315,31 @@ GuC-based command submission :internal: GuC Firmware Layout -~~~~~~~~~~~~~~~~~~~ +------------------- .. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fwif.h :doc: GuC Firmware Layout Tracing -------- +======= This sections covers all things related to the tracepoints implemented in the i915 driver. i915_ppgtt_create and i915_ppgtt_release -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h :doc: i915_ppgtt_create and i915_ppgtt_release tracepoints i915_context_create and i915_context_free -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------- .. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h :doc: i915_context_create and i915_context_free tracepoints switch_mm -~~~~~~~~~~ +--------- .. kernel-doc:: drivers/gpu/drm/i915/i915_trace.h :doc: switch_mm tracepoint diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst index cf35c4fe992f..1903595b5310 100644 --- a/Documentation/gpu/introduction.rst +++ b/Documentation/gpu/introduction.rst @@ -1,3 +1,4 @@ +============ Introduction ============ @@ -16,7 +17,7 @@ found in current kernels. [Insert diagram of typical DRM stack here] Style Guidelines ----------------- +================ For consistency this documentation uses American English. Abbreviations are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so -- cgit v1.3-14-g43fede From 9b20fa08d3fd688c85f4a6fbfd1ee6ce58f826ee Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Jun 2016 14:49:01 +0300 Subject: Documentation/gpu: convert the KMS properties table to CSV Pandoc really did a bad job of converting the big KMS properties table to RST. Instead, put the properties into a separate plain text CSV file, and include it in the RST file. The generated output isn't very pretty, but at least the information is there, and it's stored in a format that's easier to process and improve upon at a later time. The CSV file was generated by copy-pasting the table from the HTML generated by the DocBook toolchain into LibreOffice Calc, and then saved as CSV, unmodified. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/17053ff08caf5cfac4f478437ef796f83a31d772.1466506505.git.jani.nikula@intel.com --- Documentation/gpu/drm-internals.rst | 260 +---------------------------------- Documentation/gpu/kms-properties.csv | 128 +++++++++++++++++ 2 files changed, 131 insertions(+), 257 deletions(-) create mode 100644 Documentation/gpu/kms-properties.csv (limited to 'Documentation') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index ee01a4fbd657..a7f117653033 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -1532,263 +1532,9 @@ Existing KMS Properties The following table gives description of drm properties exposed by various modules/drivers. -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Owner Module/Drivers | Group | Property Name | Type | Property Values | Object attached | Description/Restrictions | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| DRM | Generic | “rotation” | BITMASK | { 0, "rotate-0" }, { 1, "rotate-90" }, { 2, "rotate-180" }, { 3, "rotate-270" }, { 4, "reflect-x" }, { 5, "reflect-y" } | CRTC, Plane | rotate-(degrees) rotates the image by the specified amount in degrees in counter clockwise direction. reflect-x and reflect-y reflects the image along the specified axis prior to rotation | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “scaling mode” | ENUM | { "None", "Full", "Center", "Full aspect" } | Connector | Supported by: amdgpu, gma500, i915, nouveau and radeon. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Connector | “EDID” | BLOB \| IMMUTABLE | 0 | Connector | Contains id of edid blob ptr object. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “DPMS” | ENUM | { “On”, “Standby”, “Suspend”, “Off” } | Connector | Contains DPMS operation mode value. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “PATH” | BLOB \| IMMUTABLE | 0 | Connector | Contains topology path to a connector. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “TILE” | BLOB \| IMMUTABLE | 0 | Connector | Contains tiling information for a connector. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Connector | CRTC that connector is attached to (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Plane | “type” | ENUM \| IMMUTABLE | { "Overlay", "Primary", "Cursor" } | Plane | Plane type | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_X” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source x coordinate in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_Y” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source y coordinate in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source width in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “SRC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout source height in 16.16 fixed point (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_X” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) x coordinate (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_Y” | SIGNED_RANGE | Min=INT_MIN, Max=INT_MAX | Plane | Scanout CRTC (destination) y coordinate (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_W” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) width (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_H” | RANGE | Min=0, Max=UINT_MAX | Plane | Scanout CRTC (destination) height (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “FB_ID” | OBJECT | DRM_MODE_OBJECT_FB | Plane | Scanout framebuffer (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CRTC_ID” | OBJECT | DRM_MODE_OBJECT_CRTC | Plane | CRTC that plane is attached to (atomic) | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| DVI-I | “subconnector” | ENUM | { “Unknown”, “DVI-D”, “DVI-A” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “select subconnector” | ENUM | { “Automatic”, “DVI-D”, “DVI-A” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| TV | “subconnector” | ENUM | { "Unknown", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “select subconnector” | ENUM | { "Automatic", "Composite", "SVIDEO", "Component", "SCART" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “left margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “right margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “top margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “bottom margin” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “brightness” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker reduction” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “overscan” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Virtual GPU | “suggested X” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an X offset for a connector | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “suggested Y” | RANGE | Min=0, Max=0xffffffff | Connector | property to suggest an Y offset for a connector | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Optional | "aspect ratio" | ENUM | { "None", "4:3", "16:9" } | Connector | TDB | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dirty” | ENUM \| IMMUTABLE | { "Off", "On", "Annotate" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “DEGAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “DEGAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the DEGAMMA_LUT property (the size depends on the underlying hardware). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “CTM” | BLOB | 0 | CRTC | DRM property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is an interpreted as a struct drm_color_ctm. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “GAMMA_LUT” | BLOB | 0 | CRTC | DRM property to set the gamma lookup table (LUT) mapping pixel data after to the transformation matrix to data sent to the connector. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “GAMMA_LUT_SIZE” | RANGE \| IMMUTABLE | Min=0, Max=UINT_MAX | CRTC | DRM property to gives the size of the lookup table to be set on the GAMMA_LUT property (the size depends on the underlying hardware). | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| i915 | Generic | "Broadcast RGB" | ENUM | { "Automatic", "Full", "Limited 16:235" } | Connector | When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255. | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “audio” | ENUM | { "force-dvi", "off", "auto", "on" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| CDV gma-500 | Generic | "Broadcast RGB" | ENUM | { “Full”, “Limited 16:235” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "Broadcast RGB" | ENUM | { “off”, “auto”, “on” } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Poulsbo | Generic | “backlight” | RANGE | Min=0, Max=100 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV | “mode” | ENUM | { "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc. | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "left_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "right_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "top_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "bottom_margin" | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “vpos” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “sharpness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_adaptive” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “flicker_filter_2d” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_chroma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “tv_luma_filter” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dot_crawl” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| SDVO-TV/LVDS | “brightness” | RANGE | Min=0, Max= SDVO dependent | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| armada | CRTC | "CSC_YUV" | ENUM | { "Auto" , "CCIR601", "CCIR709" } | CRTC | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "CSC_RGB" | ENUM | { "Auto", "Computer system", "Studio" } | CRTC | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Overlay | "colorkey" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_min" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_max" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_val" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_alpha" | RANGE | Min=0, Max=0xffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey_mode" | ENUM | { "disabled", "Y component", "U component" , "V component", "RGB", “R component", "G component", "B component" } | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "brightness" | RANGE | Min=0, Max=256 + 255 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "contrast" | RANGE | Min=0, Max=0x7fff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "saturation" | RANGE | Min=0, Max=0x7fff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| exynos | CRTC | “mode” | ENUM | { "normal", "blank" } | CRTC | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Overlay | “zpos” | RANGE | Min=0, Max=MAX_PLANE-1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| i2c/ch7006_drv | Generic | “scale” | RANGE | Min=0, Max=2 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| TV | “mode” | ENUM | { "PAL", "PAL-M","PAL-N"}, ”PAL-Nc" , "PAL-60", "NTSC-M", "NTSC-J" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| nouveau | NV10 Overlay | "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “contrast” | RANGE | Min=0, Max=8192-1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “hue” | RANGE | Min=0, Max=359 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “saturation” | RANGE | Min=0, Max=8192-1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “iturbt_709” | RANGE | Min=0, Max=1 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Nv04 Overlay | “colorkey” | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “brightness” | RANGE | Min=0, Max=1024 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Display | “dithering mode” | ENUM | { "auto", "off", "on" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “dithering depth” | ENUM | { "auto", "off", "on", "static 2x2", "dynamic 2x2", "temporal" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “underscan” | ENUM | { "auto", "6 bpc", "8 bpc" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “underscan hborder” | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “underscan vborder” | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “vibrant hue” | RANGE | Min=0, Max=180 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| “color vibrance” | RANGE | Min=0, Max=200 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| omap | Generic | “zorder” | RANGE | Min=0, Max=3 | CRTC, Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| qxl | Generic | “hotplug_mode_update" | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| radeon | DVI-I | “coherent” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| DAC enable load detect | “load detection” | RANGE | Min=0, Max=1 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| TV Standard | "tv standard" | ENUM | { "ntsc", "pal", "pal-m", "pal-60", "ntsc-j" , "scart-pal", "pal-cn", "secam" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| legacy TMDS PLL detect | "tmds_pll" | ENUM | { "driver", "bios" } | - | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Underscan | "underscan" | ENUM | { "off", "on", "auto" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "underscan hborder" | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "underscan vborder" | RANGE | Min=0, Max=128 | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Audio | “audio” | ENUM | { "off", "on", "auto" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| FMT Dithering | “dither” | ENUM | { "off", "on" } | Connector | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| rcar-du | Generic | "alpha" | RANGE | Min=0, Max=255 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "colorkey" | RANGE | Min=0, Max=0x01ffffff | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| "zpos" | RANGE | Min=1, Max=7 | Plane | TBD | -+-------------------------------+----------------------+--------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +.. csv-table:: + :header-rows: 1 + :file: kms-properties.csv Vertical Blanking ================= diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv new file mode 100644 index 000000000000..b6fcaf639c04 --- /dev/null +++ b/Documentation/gpu/kms-properties.csv @@ -0,0 +1,128 @@ +Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,Description/Restrictions +DRM,Generic,“rotation”,BITMASK,"{ 0, ""rotate-0"" }, { 1, ""rotate-90"" }, { 2, ""rotate-180"" }, { 3, ""rotate-270"" }, { 4, ""reflect-x"" }, { 5, ""reflect-y"" }","CRTC, Plane",rotate-(degrees) rotates the image by the specified amount in degrees in counter clockwise direction. reflect-x and reflect-y reflects the image along the specified axis prior to rotation +,,“scaling mode”,ENUM,"{ ""None"", ""Full"", ""Center"", ""Full aspect"" }",Connector,"Supported by: amdgpu, gma500, i915, nouveau and radeon." +,Connector,“EDID”,BLOB | IMMUTABLE,0,Connector,Contains id of edid blob ptr object. +,,“DPMS”,ENUM,"{ “On”, “Standby”, “Suspend”, “Off” }",Connector,Contains DPMS operation mode value. +,,“PATH”,BLOB | IMMUTABLE,0,Connector,Contains topology path to a connector. +,,“TILE”,BLOB | IMMUTABLE,0,Connector,Contains tiling information for a connector. +,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Connector,CRTC that connector is attached to (atomic) +,Plane,“type”,ENUM | IMMUTABLE,"{ ""Overlay"", ""Primary"", ""Cursor"" }",Plane,Plane type +,,“SRC_X”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout source x coordinate in 16.16 fixed point (atomic) +,,“SRC_Y”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout source y coordinate in 16.16 fixed point (atomic) +,,“SRC_W”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout source width in 16.16 fixed point (atomic) +,,“SRC_H”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout source height in 16.16 fixed point (atomic) +,,“CRTC_X”,SIGNED_RANGE,"Min=INT_MIN, Max=INT_MAX",Plane,Scanout CRTC (destination) x coordinate (atomic) +,,“CRTC_Y”,SIGNED_RANGE,"Min=INT_MIN, Max=INT_MAX",Plane,Scanout CRTC (destination) y coordinate (atomic) +,,“CRTC_W”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout CRTC (destination) width (atomic) +,,“CRTC_H”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout CRTC (destination) height (atomic) +,,“FB_ID”,OBJECT,DRM_MODE_OBJECT_FB,Plane,Scanout framebuffer (atomic) +,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Plane,CRTC that plane is attached to (atomic) +,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD +,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD +,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD +,,“select subconnector”,ENUM,"{ ""Automatic"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD +,,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD +,,“left margin”,RANGE,"Min=0, Max=100",Connector,TBD +,,“right margin”,RANGE,"Min=0, Max=100",Connector,TBD +,,“top margin”,RANGE,"Min=0, Max=100",Connector,TBD +,,“bottom margin”,RANGE,"Min=0, Max=100",Connector,TBD +,,“brightness”,RANGE,"Min=0, Max=100",Connector,TBD +,,“contrast”,RANGE,"Min=0, Max=100",Connector,TBD +,,“flicker reduction”,RANGE,"Min=0, Max=100",Connector,TBD +,,“overscan”,RANGE,"Min=0, Max=100",Connector,TBD +,,“saturation”,RANGE,"Min=0, Max=100",Connector,TBD +,,“hue”,RANGE,"Min=0, Max=100",Connector,TBD +,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector +,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector +,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB +,,“dirty”,ENUM | IMMUTABLE,"{ ""Off"", ""On"", ""Annotate"" }",Connector,TBD +,,“DEGAMMA_LUT”,BLOB,0,CRTC,DRM property to set the degamma lookup table (LUT) mapping pixel data from the framebuffer before it is given to the transformation matrix. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). +,,“DEGAMMA_LUT_SIZE”,RANGE | IMMUTABLE,"Min=0, Max=UINT_MAX",CRTC,DRM property to gives the size of the lookup table to be set on the DEGAMMA_LUT property (the size depends on the underlying hardware). +,,“CTM”,BLOB,0,CRTC,DRM property to set the current transformation matrix (CTM) apply to pixel data after the lookup through the degamma LUT and before the lookup through the gamma LUT. The data is an interpreted as a struct drm_color_ctm. +,,“GAMMA_LUT”,BLOB,0,CRTC,DRM property to set the gamma lookup table (LUT) mapping pixel data after to the transformation matrix to data sent to the connector. The data is an interpreted as an array of struct drm_color_lut elements. Hardware might choose not to use the full precision of the LUT elements nor use all the elements of the LUT (for example the hardware might choose to interpolate between LUT[0] and LUT[4]). +,,“GAMMA_LUT_SIZE”,RANGE | IMMUTABLE,"Min=0, Max=UINT_MAX",CRTC,DRM property to gives the size of the lookup table to be set on the GAMMA_LUT property (the size depends on the underlying hardware). +i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255." +,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD +,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD +,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,"""right_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,"""top_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,"""bottom_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“hpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“vpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“contrast”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“saturation”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“hue”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“sharpness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“flicker_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“flicker_filter_adaptive”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“flicker_filter_2d”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“tv_chroma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“tv_luma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“dot_crawl”,RANGE,"Min=0, Max=1",Connector,TBD +,SDVO-TV/LVDS,“brightness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +CDV gma-500,Generic,"""Broadcast RGB""",ENUM,"{ “Full”, “Limited 16:235” }",Connector,TBD +,,"""Broadcast RGB""",ENUM,"{ “off”, “auto”, “on” }",Connector,TBD +Poulsbo,Generic,“backlight”,RANGE,"Min=0, Max=100",Connector,TBD +,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD +,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,"""right_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,"""top_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,"""bottom_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“hpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“vpos”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“contrast”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“saturation”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“hue”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“sharpness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“flicker_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“flicker_filter_adaptive”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“flicker_filter_2d”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“tv_chroma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“tv_luma_filter”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +,,“dot_crawl”,RANGE,"Min=0, Max=1",Connector,TBD +,SDVO-TV/LVDS,“brightness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD +armada,CRTC,"""CSC_YUV""",ENUM,"{ ""Auto"" , ""CCIR601"", ""CCIR709"" }",CRTC,TBD +,,"""CSC_RGB""",ENUM,"{ ""Auto"", ""Computer system"", ""Studio"" }",CRTC,TBD +,Overlay,"""colorkey""",RANGE,"Min=0, Max=0xffffff",Plane,TBD +,,"""colorkey_min""",RANGE,"Min=0, Max=0xffffff",Plane,TBD +,,"""colorkey_max""",RANGE,"Min=0, Max=0xffffff",Plane,TBD +,,"""colorkey_val""",RANGE,"Min=0, Max=0xffffff",Plane,TBD +,,"""colorkey_alpha""",RANGE,"Min=0, Max=0xffffff",Plane,TBD +,,"""colorkey_mode""",ENUM,"{ ""disabled"", ""Y component"", ""U component"" , ""V component"", ""RGB"", “R component"", ""G component"", ""B component"" }",Plane,TBD +,,"""brightness""",RANGE,"Min=0, Max=256 + 255",Plane,TBD +,,"""contrast""",RANGE,"Min=0, Max=0x7fff",Plane,TBD +,,"""saturation""",RANGE,"Min=0, Max=0x7fff",Plane,TBD +exynos,CRTC,“mode”,ENUM,"{ ""normal"", ""blank"" }",CRTC,TBD +,Overlay,“zpos”,RANGE,"Min=0, Max=MAX_PLANE-1",Plane,TBD +i2c/ch7006_drv,Generic,“scale”,RANGE,"Min=0, Max=2",Connector,TBD +,TV,“mode”,ENUM,"{ ""PAL"", ""PAL-M"",""PAL-N""}, ”PAL-Nc"" , ""PAL-60"", ""NTSC-M"", ""NTSC-J"" }",Connector,TBD +nouveau,NV10 Overlay,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD +,,“contrast”,RANGE,"Min=0, Max=8192-1",Plane,TBD +,,“brightness”,RANGE,"Min=0, Max=1024",Plane,TBD +,,“hue”,RANGE,"Min=0, Max=359",Plane,TBD +,,“saturation”,RANGE,"Min=0, Max=8192-1",Plane,TBD +,,“iturbt_709”,RANGE,"Min=0, Max=1",Plane,TBD +,Nv04 Overlay,“colorkey”,RANGE,"Min=0, Max=0x01ffffff",Plane,TBD +,,“brightness”,RANGE,"Min=0, Max=1024",Plane,TBD +,Display,“dithering mode”,ENUM,"{ ""auto"", ""off"", ""on"" }",Connector,TBD +,,“dithering depth”,ENUM,"{ ""auto"", ""off"", ""on"", ""static 2x2"", ""dynamic 2x2"", ""temporal"" }",Connector,TBD +,,“underscan”,ENUM,"{ ""auto"", ""6 bpc"", ""8 bpc"" }",Connector,TBD +,,“underscan hborder”,RANGE,"Min=0, Max=128",Connector,TBD +,,“underscan vborder”,RANGE,"Min=0, Max=128",Connector,TBD +,,“vibrant hue”,RANGE,"Min=0, Max=180",Connector,TBD +,,“color vibrance”,RANGE,"Min=0, Max=200",Connector,TBD +omap,Generic,“zorder”,RANGE,"Min=0, Max=3","CRTC, Plane",TBD +qxl,Generic,"“hotplug_mode_update""",RANGE,"Min=0, Max=1",Connector,TBD +radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD +,DAC enable load detect,“load detection”,RANGE,"Min=0, Max=1",Connector,TBD +,TV Standard,"""tv standard""",ENUM,"{ ""ntsc"", ""pal"", ""pal-m"", ""pal-60"", ""ntsc-j"" , ""scart-pal"", ""pal-cn"", ""secam"" }",Connector,TBD +,legacy TMDS PLL detect,"""tmds_pll""",ENUM,"{ ""driver"", ""bios"" }",-,TBD +,Underscan,"""underscan""",ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD +,,"""underscan hborder""",RANGE,"Min=0, Max=128",Connector,TBD +,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD +,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD +,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD +rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD +,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD +,,"""zpos""",RANGE,"Min=1, Max=7",Plane,TBD -- cgit v1.3-14-g43fede From 2fa91d15588c1736833b3eb48406a0eece41a932 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Jun 2016 14:49:02 +0300 Subject: Documentation/gpu: split up mm, kms and kms-helpers from internals Make the documents more manageable. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/be992e56eb8442d6e03b52444df5a42525085718.1466506505.git.jani.nikula@intel.com --- Documentation/gpu/drm-internals.rst | 1379 +-------------------------------- Documentation/gpu/drm-kms-helpers.rst | 260 +++++++ Documentation/gpu/drm-kms.rst | 656 ++++++++++++++++ Documentation/gpu/drm-mm.rst | 454 +++++++++++ Documentation/gpu/index.rst | 3 + 5 files changed, 1379 insertions(+), 1373 deletions(-) create mode 100644 Documentation/gpu/drm-kms-helpers.rst create mode 100644 Documentation/gpu/drm-kms.rst create mode 100644 Documentation/gpu/drm-mm.rst (limited to 'Documentation') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index a7f117653033..4f7176576feb 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -40,7 +40,7 @@ Driver Information ------------------ Driver Features -^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~ Drivers inform the DRM core about their requirements and supported features by setting appropriate flags in the driver_features field. @@ -96,7 +96,7 @@ DRIVER_ATOMIC modeset objects with driver specific properties. Major, Minor and Patchlevel -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ int major; int minor; int patchlevel; The DRM core identifies driver versions by a major, minor and patch @@ -114,7 +114,7 @@ return an error. Otherwise the driver's set_version() method will be called with the requested version. Name, Description and Date -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ char \*name; char \*desc; char \*date; The driver name is printed to the kernel log at initialization time, @@ -144,7 +144,7 @@ Driver Load ----------- IRQ Registration -^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~ The DRM core tries to facilitate IRQ handler registration and unregistration by providing :c:func:`drm_irq_install()` and @@ -198,7 +198,7 @@ registration of the IRQs, and clear it to 0 after unregistering the IRQs. Memory Manager Initialization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Every DRM driver requires a memory manager which must be initialized at load time. DRM currently contains two memory managers, the Translation @@ -207,7 +207,7 @@ document describes the use of the GEM memory manager only. See ? for details. Miscellaneous Device Configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another task that may be necessary for PCI devices during configuration is mapping the video BIOS. On many devices, the VBIOS describes device @@ -236,1373 +236,6 @@ drivers. .. kernel-doc:: drivers/gpu/drm/drm_platform.c :export: -Memory management -================= - -Modern Linux systems require large amount of graphics memory to store -frame buffers, textures, vertices and other graphics-related data. Given -the very dynamic nature of many of that data, managing graphics memory -efficiently is thus crucial for the graphics stack and plays a central -role in the DRM infrastructure. - -The DRM core includes two memory managers, namely Translation Table Maps -(TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory -manager to be developed and tried to be a one-size-fits-them all -solution. It provides a single userspace API to accommodate the need of -all hardware, supporting both Unified Memory Architecture (UMA) devices -and devices with dedicated video RAM (i.e. most discrete video cards). -This resulted in a large, complex piece of code that turned out to be -hard to use for driver development. - -GEM started as an Intel-sponsored project in reaction to TTM's -complexity. Its design philosophy is completely different: instead of -providing a solution to every graphics memory-related problems, GEM -identified common code between drivers and created a support library to -share it. GEM has simpler initialization and execution requirements than -TTM, but has no video RAM management capabilities and is thus limited to -UMA devices. - -The Translation Table Manager (TTM) ------------------------------------ - -TTM design background and information belongs here. - -TTM initialization -^^^^^^^^^^^^^^^^^^ - - **Warning** - - This section is outdated. - -Drivers wishing to support TTM must fill out a drm_bo_driver -structure. The structure contains several fields with function pointers -for initializing the TTM, allocating and freeing memory, waiting for -command completion and fence synchronization, and memory migration. See -the radeon_ttm.c file for an example of usage. - -The ttm_global_reference structure is made up of several fields: - -:: - - struct ttm_global_reference { - enum ttm_global_types global_type; - size_t size; - void *object; - int (*init) (struct ttm_global_reference *); - void (*release) (struct ttm_global_reference *); - }; - - -There should be one global reference structure for your memory manager -as a whole, and there will be others for each object created by the -memory manager at runtime. Your global TTM should have a type of -TTM_GLOBAL_TTM_MEM. The size field for the global object should be -sizeof(struct ttm_mem_global), and the init and release hooks should -point at your driver-specific init and release routines, which probably -eventually call ttm_mem_global_init and ttm_mem_global_release, -respectively. - -Once your global TTM accounting structure is set up and initialized by -calling ttm_global_item_ref() on it, you need to create a buffer -object TTM to provide a pool for buffer object allocation by clients and -the kernel itself. The type of this object should be -TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct -ttm_bo_global). Again, driver-specific init and release functions may -be provided, likely eventually calling ttm_bo_global_init() and -ttm_bo_global_release(), respectively. Also, like the previous -object, ttm_global_item_ref() is used to create an initial reference -count for the TTM, which will call your initialization function. - -The Graphics Execution Manager (GEM) ------------------------------------- - -The GEM design approach has resulted in a memory manager that doesn't -provide full coverage of all (or even all common) use cases in its -userspace or kernel API. GEM exposes a set of standard memory-related -operations to userspace and a set of helper functions to drivers, and -let drivers implement hardware-specific operations with their own -private API. - -The GEM userspace API is described in the `GEM - the Graphics Execution -Manager `__ article on LWN. While -slightly outdated, the document provides a good overview of the GEM API -principles. Buffer allocation and read and write operations, described -as part of the common GEM API, are currently implemented using -driver-specific ioctls. - -GEM is data-agnostic. It manages abstract buffer objects without knowing -what individual buffers contain. APIs that require knowledge of buffer -contents or purpose, such as buffer allocation or synchronization -primitives, are thus outside of the scope of GEM and must be implemented -using driver-specific ioctls. - -On a fundamental level, GEM involves several operations: - -- Memory allocation and freeing -- Command execution -- Aperture management at command execution time - -Buffer object allocation is relatively straightforward and largely -provided by Linux's shmem layer, which provides memory to back each -object. - -Device-specific operations, such as command execution, pinning, buffer -read & write, mapping, and domain ownership transfers are left to -driver-specific ioctls. - -GEM Initialization -^^^^^^^^^^^^^^^^^^ - -Drivers that use GEM must set the DRIVER_GEM bit in the struct -:c:type:`struct drm_driver ` driver_features -field. The DRM core will then automatically initialize the GEM core -before calling the load operation. Behind the scene, this will create a -DRM Memory Manager object which provides an address space pool for -object allocation. - -In a KMS configuration, drivers need to allocate and initialize a -command ring buffer following core GEM initialization if required by the -hardware. UMA devices usually have what is called a "stolen" memory -region, which provides space for the initial framebuffer and large, -contiguous memory regions required by the device. This space is -typically not managed by GEM, and must be initialized separately into -its own DRM MM object. - -GEM Objects Creation -^^^^^^^^^^^^^^^^^^^^ - -GEM splits creation of GEM objects and allocation of the memory that -backs them in two distinct operations. - -GEM objects are represented by an instance of struct :c:type:`struct -drm_gem_object `. Drivers usually need to -extend GEM objects with private information and thus create a -driver-specific GEM object structure type that embeds an instance of -struct :c:type:`struct drm_gem_object `. - -To create a GEM object, a driver allocates memory for an instance of its -specific GEM object type and initializes the embedded struct -:c:type:`struct drm_gem_object ` with a call -to :c:func:`drm_gem_object_init()`. The function takes a pointer -to the DRM device, a pointer to the GEM object and the buffer object -size in bytes. - -GEM uses shmem to allocate anonymous pageable memory. -:c:func:`drm_gem_object_init()` will create an shmfs file of the -requested size and store it into the struct :c:type:`struct -drm_gem_object ` filp field. The memory is -used as either main storage for the object when the graphics hardware -uses system memory directly or as a backing store otherwise. - -Drivers are responsible for the actual physical pages allocation by -calling :c:func:`shmem_read_mapping_page_gfp()` for each page. -Note that they can decide to allocate pages when initializing the GEM -object, or to delay allocation until the memory is needed (for instance -when a page fault occurs as a result of a userspace memory access or -when the driver needs to start a DMA transfer involving the memory). - -Anonymous pageable memory allocation is not always desired, for instance -when the hardware requires physically contiguous system memory as is -often the case in embedded devices. Drivers can create GEM objects with -no shmfs backing (called private GEM objects) by initializing them with -a call to :c:func:`drm_gem_private_object_init()` instead of -:c:func:`drm_gem_object_init()`. Storage for private GEM objects -must be managed by drivers. - -GEM Objects Lifetime -^^^^^^^^^^^^^^^^^^^^ - -All GEM objects are reference-counted by the GEM core. References can be -acquired and release by :c:func:`calling -drm_gem_object_reference()` and -:c:func:`drm_gem_object_unreference()` respectively. The caller -must hold the :c:type:`struct drm_device ` -struct_mutex lock when calling -:c:func:`drm_gem_object_reference()`. As a convenience, GEM -provides :c:func:`drm_gem_object_unreference_unlocked()` -functions that can be called without holding the lock. - -When the last reference to a GEM object is released the GEM core calls -the :c:type:`struct drm_driver ` gem_free_object -operation. That operation is mandatory for GEM-enabled drivers and must -free the GEM object and all associated resources. - -void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are -responsible for freeing all GEM object resources. This includes the -resources created by the GEM core, which need to be released with -:c:func:`drm_gem_object_release()`. - -GEM Objects Naming -^^^^^^^^^^^^^^^^^^ - -Communication between userspace and the kernel refers to GEM objects -using local handles, global names or, more recently, file descriptors. -All of those are 32-bit integer values; the usual Linux kernel limits -apply to the file descriptors. - -GEM handles are local to a DRM file. Applications get a handle to a GEM -object through a driver-specific ioctl, and can use that handle to refer -to the GEM object in other standard or driver-specific ioctls. Closing a -DRM file handle frees all its GEM handles and dereferences the -associated GEM objects. - -To create a handle for a GEM object drivers call -:c:func:`drm_gem_handle_create()`. The function takes a pointer -to the DRM file and the GEM object and returns a locally unique handle. -When the handle is no longer needed drivers delete it with a call to -:c:func:`drm_gem_handle_delete()`. Finally the GEM object -associated with a handle can be retrieved by a call to -:c:func:`drm_gem_object_lookup()`. - -Handles don't take ownership of GEM objects, they only take a reference -to the object that will be dropped when the handle is destroyed. To -avoid leaking GEM objects, drivers must make sure they drop the -reference(s) they own (such as the initial reference taken at object -creation time) as appropriate, without any special consideration for the -handle. For example, in the particular case of combined GEM object and -handle creation in the implementation of the dumb_create operation, -drivers must drop the initial reference to the GEM object before -returning the handle. - -GEM names are similar in purpose to handles but are not local to DRM -files. They can be passed between processes to reference a GEM object -globally. Names can't be used directly to refer to objects in the DRM -API, applications must convert handles to names and names to handles -using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls -respectively. The conversion is handled by the DRM core without any -driver-specific support. - -GEM also supports buffer sharing with dma-buf file descriptors through -PRIME. GEM-based drivers must use the provided helpers functions to -implement the exporting and importing correctly. See ?. Since sharing -file descriptors is inherently more secure than the easily guessable and -global GEM names it is the preferred buffer sharing mechanism. Sharing -buffers through GEM names is only supported for legacy userspace. -Furthermore PRIME also allows cross-device buffer sharing since it is -based on dma-bufs. - -GEM Objects Mapping -^^^^^^^^^^^^^^^^^^^ - -Because mapping operations are fairly heavyweight GEM favours -read/write-like access to buffers, implemented through driver-specific -ioctls, over mapping buffers to userspace. However, when random access -to the buffer is needed (to perform software rendering for instance), -direct access to the object can be more efficient. - -The mmap system call can't be used directly to map GEM objects, as they -don't have their own file handle. Two alternative methods currently -co-exist to map GEM objects to userspace. The first method uses a -driver-specific ioctl to perform the mapping operation, calling -:c:func:`do_mmap()` under the hood. This is often considered -dubious, seems to be discouraged for new GEM-enabled drivers, and will -thus not be described here. - -The second method uses the mmap system call on the DRM file handle. void -\*mmap(void \*addr, size_t length, int prot, int flags, int fd, off_t -offset); DRM identifies the GEM object to be mapped by a fake offset -passed through the mmap offset argument. Prior to being mapped, a GEM -object must thus be associated with a fake offset. To do so, drivers -must call :c:func:`drm_gem_create_mmap_offset()` on the object. - -Once allocated, the fake offset value must be passed to the application -in a driver-specific way and can then be used as the mmap offset -argument. - -The GEM core provides a helper method :c:func:`drm_gem_mmap()` to -handle object mapping. The method can be set directly as the mmap file -operation handler. It will look up the GEM object based on the offset -value and set the VMA operations to the :c:type:`struct drm_driver -` gem_vm_ops field. Note that -:c:func:`drm_gem_mmap()` doesn't map memory to userspace, but -relies on the driver-provided fault handler to map pages individually. - -To use :c:func:`drm_gem_mmap()`, drivers must fill the struct -:c:type:`struct drm_driver ` gem_vm_ops field -with a pointer to VM operations. - -struct vm_operations_struct \*gem_vm_ops struct -vm_operations_struct { void (\*open)(struct vm_area_struct \* area); -void (\*close)(struct vm_area_struct \* area); int (\*fault)(struct -vm_area_struct \*vma, struct vm_fault \*vmf); }; - -The open and close operations must update the GEM object reference -count. Drivers can use the :c:func:`drm_gem_vm_open()` and -:c:func:`drm_gem_vm_close()` helper functions directly as open -and close handlers. - -The fault operation handler is responsible for mapping individual pages -to userspace when a page fault occurs. Depending on the memory -allocation scheme, drivers can allocate pages at fault time, or can -decide to allocate memory for the GEM object at the time the object is -created. - -Drivers that want to map the GEM object upfront instead of handling page -faults can implement their own mmap file operation handler. - -Memory Coherency -^^^^^^^^^^^^^^^^ - -When mapped to the device or used in a command buffer, backing pages for -an object are flushed to memory and marked write combined so as to be -coherent with the GPU. Likewise, if the CPU accesses an object after the -GPU has finished rendering to the object, then the object must be made -coherent with the CPU's view of memory, usually involving GPU cache -flushing of various kinds. This core CPU<->GPU coherency management is -provided by a device-specific ioctl, which evaluates an object's current -domain and performs any necessary flushing or synchronization to put the -object into the desired coherency domain (note that the object may be -busy, i.e. an active render target; in that case, setting the domain -blocks the client and waits for rendering to complete before performing -any necessary flushing operations). - -Command Execution -^^^^^^^^^^^^^^^^^ - -Perhaps the most important GEM function for GPU devices is providing a -command execution interface to clients. Client programs construct -command buffers containing references to previously allocated memory -objects, and then submit them to GEM. At that point, GEM takes care to -bind all the objects into the GTT, execute the buffer, and provide -necessary synchronization between clients accessing the same buffers. -This often involves evicting some objects from the GTT and re-binding -others (a fairly expensive operation), and providing relocation support -which hides fixed GTT offsets from clients. Clients must take care not -to submit command buffers that reference more objects than can fit in -the GTT; otherwise, GEM will reject them and no rendering will occur. -Similarly, if several objects in the buffer require fence registers to -be allocated for correct rendering (e.g. 2D blits on pre-965 chips), -care must be taken not to require more fence registers than are -available to the client. Such resource management should be abstracted -from the client in libdrm. - -GEM Function Reference ----------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_gem.c - :export: - -.. kernel-doc:: include/drm/drm_gem.h - :internal: - -VMA Offset Manager ------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c - :doc: vma offset manager - -.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c - :export: - -.. kernel-doc:: include/drm/drm_vma_manager.h - :internal: - -PRIME Buffer Sharing --------------------- - -PRIME is the cross device buffer sharing framework in drm, originally -created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME -buffers are dma-buf based file descriptors. - -Overview and Driver Interface -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Similar to GEM global names, PRIME file descriptors are also used to -share buffer objects across processes. They offer additional security: -as file descriptors must be explicitly sent over UNIX domain sockets to -be shared between applications, they can't be guessed like the globally -unique GEM names. - -Drivers that support the PRIME API must set the DRIVER_PRIME bit in the -struct :c:type:`struct drm_driver ` -driver_features field, and implement the prime_handle_to_fd and -prime_fd_to_handle operations. - -int (\*prime_handle_to_fd)(struct drm_device \*dev, struct drm_file -\*file_priv, uint32_t handle, uint32_t flags, int \*prime_fd); int -(\*prime_fd_to_handle)(struct drm_device \*dev, struct drm_file -\*file_priv, int prime_fd, uint32_t \*handle); Those two operations -convert a handle to a PRIME file descriptor and vice versa. Drivers must -use the kernel dma-buf buffer sharing framework to manage the PRIME file -descriptors. Similar to the mode setting API PRIME is agnostic to the -underlying buffer object manager, as long as handles are 32bit unsigned -integers. - -While non-GEM drivers must implement the operations themselves, GEM -drivers must use the :c:func:`drm_gem_prime_handle_to_fd()` and -:c:func:`drm_gem_prime_fd_to_handle()` helper functions. Those -helpers rely on the driver gem_prime_export and gem_prime_import -operations to create a dma-buf instance from a GEM object (dma-buf -exporter role) and to create a GEM object from a dma-buf instance -(dma-buf importer role). - -struct dma_buf \* (\*gem_prime_export)(struct drm_device \*dev, -struct drm_gem_object \*obj, int flags); struct drm_gem_object \* -(\*gem_prime_import)(struct drm_device \*dev, struct dma_buf -\*dma_buf); These two operations are mandatory for GEM drivers that -support PRIME. - -PRIME Helper Functions -^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_prime.c - :doc: PRIME Helpers - -PRIME Function References -------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_prime.c - :export: - -DRM MM Range Allocator ----------------------- - -Overview -^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :doc: Overview - -LRU Scan/Eviction Support -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :doc: lru scan roaster - -DRM MM Range Allocator Function References ------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_mm.c - :export: - -.. kernel-doc:: include/drm/drm_mm.h - :internal: - -CMA Helper Functions Reference ------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c - :doc: cma helpers - -.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c - :export: - -.. kernel-doc:: include/drm/drm_gem_cma_helper.h - :internal: - -Mode Setting -============ - -Drivers must initialize the mode setting core by calling -:c:func:`drm_mode_config_init()` on the DRM device. The function -initializes the :c:type:`struct drm_device ` -mode_config field and never fails. Once done, mode configuration must -be setup by initializing the following fields. - -- int min_width, min_height; int max_width, max_height; - Minimum and maximum width and height of the frame buffers in pixel - units. - -- struct drm_mode_config_funcs \*funcs; - Mode setting functions. - -Display Modes Function Reference --------------------------------- - -.. kernel-doc:: include/drm/drm_modes.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_modes.c - :export: - -Atomic Mode Setting Function Reference --------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_atomic.c - :internal: - -Frame Buffer Abstraction ------------------------- - -Frame buffers are abstract memory objects that provide a source of -pixels to scanout to a CRTC. Applications explicitly request the -creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls -and receive an opaque handle that can be passed to the KMS CRTC control, -plane configuration and page flip functions. - -Frame buffers rely on the underneath memory manager for low-level memory -operations. When creating a frame buffer applications pass a memory -handle (or a list of memory handles for multi-planar formats) through -the ``drm_mode_fb_cmd2`` argument. For drivers using GEM as their -userspace buffer management interface this would be a GEM handle. -Drivers are however free to use their own backing storage object -handles, e.g. vmwgfx directly exposes special TTM handles to userspace -and so expects TTM handles in the create ioctl and not GEM handles. - -The lifetime of a drm framebuffer is controlled with a reference count, -drivers can grab additional references with -:c:func:`drm_framebuffer_reference()`and drop them again with -:c:func:`drm_framebuffer_unreference()`. For driver-private -framebuffers for which the last reference is never dropped (e.g. for the -fbdev framebuffer when the struct :c:type:`struct drm_framebuffer -` is embedded into the fbdev helper struct) -drivers can manually clean up a framebuffer at module unload time with -:c:func:`drm_framebuffer_unregister_private()`. - -DRM Format Handling -------------------- - -.. kernel-doc:: include/drm/drm_fourcc.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c - :export: - -Dumb Buffer Objects -------------------- - -The KMS API doesn't standardize backing storage object creation and -leaves it to driver-specific ioctls. Furthermore actually creating a -buffer object even for GEM-based drivers is done through a -driver-specific ioctl - GEM only has a common userspace interface for -sharing and destroying objects. While not an issue for full-fledged -graphics stacks that include device-specific userspace components (in -libdrm for instance), this limit makes DRM-based early boot graphics -unnecessarily complex. - -Dumb objects partly alleviate the problem by providing a standard API to -create dumb buffers suitable for scanout, which can then be used to -create KMS frame buffers. - -To support dumb objects drivers must implement the dumb_create, -dumb_destroy and dumb_map_offset operations. - -- int (\*dumb_create)(struct drm_file \*file_priv, struct - drm_device \*dev, struct drm_mode_create_dumb \*args); - The dumb_create operation creates a driver object (GEM or TTM - handle) suitable for scanout based on the width, height and depth - from the struct :c:type:`struct drm_mode_create_dumb - ` argument. It fills the argument's - handle, pitch and size fields with a handle for the newly created - object and its line pitch and size in bytes. - -- int (\*dumb_destroy)(struct drm_file \*file_priv, struct - drm_device \*dev, uint32_t handle); - The dumb_destroy operation destroys a dumb object created by - dumb_create. - -- int (\*dumb_map_offset)(struct drm_file \*file_priv, struct - drm_device \*dev, uint32_t handle, uint64_t \*offset); - The dumb_map_offset operation associates an mmap fake offset with - the object given by the handle and returns it. Drivers must use the - :c:func:`drm_gem_create_mmap_offset()` function to associate - the fake offset as described in ?. - -Note that dumb objects may not be used for gpu acceleration, as has been -attempted on some ARM embedded platforms. Such drivers really must have -a hardware-specific ioctl to allocate suitable buffer objects. - -Output Polling --------------- - -void (\*output_poll_changed)(struct drm_device \*dev); -This operation notifies the driver that the status of one or more -connectors has changed. Drivers that use the fb helper can just call the -:c:func:`drm_fb_helper_hotplug_event()` function to handle this -operation. - -KMS Initialization and Cleanup -============================== - -A KMS device is abstracted and exposed as a set of planes, CRTCs, -encoders and connectors. KMS drivers must thus create and initialize all -those objects at load time after initializing mode setting. - -CRTCs (:c:type:`struct drm_crtc `) --------------------------------------------- - -A CRTC is an abstraction representing a part of the chip that contains a -pointer to a scanout buffer. Therefore, the number of CRTCs available -determines how many independent scanout buffers can be active at any -given time. The CRTC structure contains several fields to support this: -a pointer to some video memory (abstracted as a frame buffer object), a -display mode, and an (x, y) offset into the video memory to support -panning or configurations where one piece of video memory spans multiple -CRTCs. - -CRTC Initialization -^^^^^^^^^^^^^^^^^^^ - -A KMS device must create and register at least one struct -:c:type:`struct drm_crtc ` instance. The instance is -allocated and zeroed by the driver, possibly as part of a larger -structure, and registered with a call to :c:func:`drm_crtc_init()` -with a pointer to CRTC functions. - -Planes (:c:type:`struct drm_plane `) ------------------------------------------------ - -A plane represents an image source that can be blended with or overlayed -on top of a CRTC during the scanout process. Planes are associated with -a frame buffer to crop a portion of the image memory (source) and -optionally scale it to a destination size. The result is then blended -with or overlayed on top of a CRTC. - -The DRM core recognizes three types of planes: - -- DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. - Primary planes are the planes operated upon by CRTC modesetting and - flipping operations described in the page_flip hook in - :c:type:`struct drm_crtc_funcs `. -- DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. - Cursor planes are the planes operated upon by the - DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls. -- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor - planes. Some drivers refer to these types of planes as "sprites" - internally. - -For compatibility with legacy userspace, only overlay planes are made -available to userspace by default. Userspace clients may set the -DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate -that they wish to receive a universal plane list containing all plane -types. - -Plane Initialization -^^^^^^^^^^^^^^^^^^^^ - -To create a plane, a KMS drivers allocates and zeroes an instances of -:c:type:`struct drm_plane ` (possibly as part of a -larger structure) and registers it with a call to -:c:func:`drm_universal_plane_init()`. The function takes a -bitmask of the CRTCs that can be associated with the plane, a pointer to -the plane functions, a list of format supported formats, and the type of -plane (primary, cursor, or overlay) being initialized. - -Cursor and overlay planes are optional. All drivers should provide one -primary plane per CRTC (although this requirement may change in the -future); drivers that do not wish to provide special handling for -primary planes may make use of the helper functions described in ? to -create and register a primary plane with standard capabilities. - -Encoders (:c:type:`struct drm_encoder `) ------------------------------------------------------ - -An encoder takes pixel data from a CRTC and converts it to a format -suitable for any attached connectors. On some devices, it may be -possible to have a CRTC send data to more than one encoder. In that -case, both encoders would receive data from the same scanout buffer, -resulting in a "cloned" display configuration across the connectors -attached to each encoder. - -Encoder Initialization -^^^^^^^^^^^^^^^^^^^^^^ - -As for CRTCs, a KMS driver must create, initialize and register at least -one :c:type:`struct drm_encoder ` instance. The -instance is allocated and zeroed by the driver, possibly as part of a -larger structure. - -Drivers must initialize the :c:type:`struct drm_encoder -` possible_crtcs and possible_clones fields before -registering the encoder. Both fields are bitmasks of respectively the -CRTCs that the encoder can be connected to, and sibling encoders -candidate for cloning. - -After being initialized, the encoder must be registered with a call to -:c:func:`drm_encoder_init()`. The function takes a pointer to the -encoder functions and an encoder type. Supported types are - -- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A -- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort -- DRM_MODE_ENCODER_LVDS for display panels -- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, - Component, SCART) -- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays - -Encoders must be attached to a CRTC to be used. DRM drivers leave -encoders unattached at initialization time. Applications (or the fbdev -compatibility layer when implemented) are responsible for attaching the -encoders they want to use to a CRTC. - -Connectors (:c:type:`struct drm_connector `) ------------------------------------------------------------ - -A connector is the final destination for pixel data on a device, and -usually connects directly to an external display device like a monitor -or laptop panel. A connector can only be attached to one encoder at a -time. The connector is also the structure where information about the -attached display is kept, so it contains fields for display data, EDID -data, DPMS & connection status, and information about modes supported on -the attached displays. - -Connector Initialization -^^^^^^^^^^^^^^^^^^^^^^^^ - -Finally a KMS driver must create, initialize, register and attach at -least one :c:type:`struct drm_connector ` -instance. The instance is created as other KMS objects and initialized -by setting the following fields. - -interlace_allowed - Whether the connector can handle interlaced modes. - -doublescan_allowed - Whether the connector can handle doublescan. - -display_info - Display information is filled from EDID information when a display - is detected. For non hot-pluggable displays such as flat panels in - embedded systems, the driver should initialize the - display_info.width_mm and display_info.height_mm fields with the - physical size of the display. - -polled - Connector polling mode, a combination of - - DRM_CONNECTOR_POLL_HPD - The connector generates hotplug events and doesn't need to be - periodically polled. The CONNECT and DISCONNECT flags must not - be set together with the HPD flag. - - DRM_CONNECTOR_POLL_CONNECT - Periodically poll the connector for connection. - - DRM_CONNECTOR_POLL_DISCONNECT - Periodically poll the connector for disconnection. - - Set to 0 for connectors that don't support connection status - discovery. - -The connector is then registered with a call to -:c:func:`drm_connector_init()` with a pointer to the connector -functions and a connector type, and exposed through sysfs with a call to -:c:func:`drm_connector_register()`. - -Supported connector types are - -- DRM_MODE_CONNECTOR_VGA -- DRM_MODE_CONNECTOR_DVII -- DRM_MODE_CONNECTOR_DVID -- DRM_MODE_CONNECTOR_DVIA -- DRM_MODE_CONNECTOR_Composite -- DRM_MODE_CONNECTOR_SVIDEO -- DRM_MODE_CONNECTOR_LVDS -- DRM_MODE_CONNECTOR_Component -- DRM_MODE_CONNECTOR_9PinDIN -- DRM_MODE_CONNECTOR_DisplayPort -- DRM_MODE_CONNECTOR_HDMIA -- DRM_MODE_CONNECTOR_HDMIB -- DRM_MODE_CONNECTOR_TV -- DRM_MODE_CONNECTOR_eDP -- DRM_MODE_CONNECTOR_VIRTUAL - -Connectors must be attached to an encoder to be used. For devices that -map connectors to encoders 1:1, the connector should be attached at -initialization time with a call to -:c:func:`drm_mode_connector_attach_encoder()`. The driver must -also set the :c:type:`struct drm_connector ` -encoder field to point to the attached encoder. - -Finally, drivers must initialize the connectors state change detection -with a call to :c:func:`drm_kms_helper_poll_init()`. If at least -one connector is pollable but can't generate hotplug interrupts -(indicated by the DRM_CONNECTOR_POLL_CONNECT and -DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will -automatically be queued to periodically poll for changes. Connectors -that can generate hotplug interrupts must be marked with the -DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must -call :c:func:`drm_helper_hpd_irq_event()`. The function will -queue a delayed work to check the state of all connectors, but no -periodic polling will be done. - -Connector Operations -^^^^^^^^^^^^^^^^^^^^ - - **Note** - - Unless otherwise state, all operations are mandatory. - -DPMS -'''' - -void (\*dpms)(struct drm_connector \*connector, int mode); -The DPMS operation sets the power state of a connector. The mode -argument is one of - -- DRM_MODE_DPMS_ON - -- DRM_MODE_DPMS_STANDBY - -- DRM_MODE_DPMS_SUSPEND - -- DRM_MODE_DPMS_OFF - -In all but DPMS_ON mode the encoder to which the connector is attached -should put the display in low-power mode by driving its signals -appropriately. If more than one connector is attached to the encoder -care should be taken not to change the power state of other displays as -a side effect. Low-power mode should be propagated to the encoders and -CRTCs when all related connectors are put in low-power mode. - -Modes -''''' - -int (\*fill_modes)(struct drm_connector \*connector, uint32_t -max_width, uint32_t max_height); -Fill the mode list with all supported modes for the connector. If the -``max_width`` and ``max_height`` arguments are non-zero, the -implementation must ignore all modes wider than ``max_width`` or higher -than ``max_height``. - -The connector must also fill in this operation its display_info -width_mm and height_mm fields with the connected display physical size -in millimeters. The fields should be set to 0 if the value isn't known -or is not applicable (for instance for projector devices). - -Connection Status -''''''''''''''''' - -The connection status is updated through polling or hotplug events when -supported (see ?). The status value is reported to userspace through -ioctls and must not be used inside the driver, as it only gets -initialized by a call to :c:func:`drm_mode_getconnector()` from -userspace. - -enum drm_connector_status (\*detect)(struct drm_connector -\*connector, bool force); -Check to see if anything is attached to the connector. The ``force`` -parameter is set to false whilst polling or to true when checking the -connector due to user request. ``force`` can be used by the driver to -avoid expensive, destructive operations during automated probing. - -Return connector_status_connected if something is connected to the -connector, connector_status_disconnected if nothing is connected and -connector_status_unknown if the connection state isn't known. - -Drivers should only return connector_status_connected if the -connection status has really been probed as connected. Connectors that -can't detect the connection status, or failed connection status probes, -should return connector_status_unknown. - -Cleanup -------- - -The DRM core manages its objects' lifetime. When an object is not needed -anymore the core calls its destroy function, which must clean up and -free every resource allocated for the object. Every -:c:func:`drm_\*_init()` call must be matched with a corresponding -:c:func:`drm_\*_cleanup()` call to cleanup CRTCs -(:c:func:`drm_crtc_cleanup()`), planes -(:c:func:`drm_plane_cleanup()`), encoders -(:c:func:`drm_encoder_cleanup()`) and connectors -(:c:func:`drm_connector_cleanup()`). Furthermore, connectors that -have been added to sysfs must be removed by a call to -:c:func:`drm_connector_unregister()` before calling -:c:func:`drm_connector_cleanup()`. - -Connectors state change detection must be cleanup up with a call to -:c:func:`drm_kms_helper_poll_fini()`. - -Output discovery and initialization example -------------------------------------------- - -:: - - void intel_crt_init(struct drm_device *dev) - { - struct drm_connector *connector; - struct intel_output *intel_output; - - intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) - return; - - connector = &intel_output->base; - drm_connector_init(dev, &intel_output->base, - &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - - drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, - DRM_MODE_ENCODER_DAC); - - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); - - /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return; - } - - intel_output->type = INTEL_OUTPUT_ANALOG; - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); - drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); - - drm_connector_register(connector); - } - -In the example above (taken from the i915 driver), a CRTC, connector and -encoder combination is created. A device-specific i2c bus is also -created for fetching EDID data and performing monitor detection. Once -the process is complete, the new connector is registered with sysfs to -make its properties available to applications. - -KMS API Functions ------------------ - -.. kernel-doc:: drivers/gpu/drm/drm_crtc.c - :export: - -KMS Data Structures -------------------- - -.. kernel-doc:: include/drm/drm_crtc.h - :internal: - -KMS Locking ------------ - -.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c - :doc: kms locking - -.. kernel-doc:: include/drm/drm_modeset_lock.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c - :export: - -Mode Setting Helper Functions -============================= - -The plane, CRTC, encoder and connector functions provided by the drivers -implement the DRM API. They're called by the DRM core and ioctl handlers -to handle device state changes and configuration request. As -implementing those functions often requires logic not specific to -drivers, mid-layer helper functions are available to avoid duplicating -boilerplate code. - -The DRM core contains one mid-layer implementation. The mid-layer -provides implementations of several plane, CRTC, encoder and connector -functions (called from the top of the mid-layer) that pre-process -requests and call lower-level functions provided by the driver (at the -bottom of the mid-layer). For instance, the -:c:func:`drm_crtc_helper_set_config()` function can be used to -fill the :c:type:`struct drm_crtc_funcs ` -set_config field. When called, it will split the set_config operation -in smaller, simpler operations and call the driver to handle them. - -To use the mid-layer, drivers call -:c:func:`drm_crtc_helper_add()`, -:c:func:`drm_encoder_helper_add()` and -:c:func:`drm_connector_helper_add()` functions to install their -mid-layer bottom operations handlers, and fill the :c:type:`struct -drm_crtc_funcs `, :c:type:`struct -drm_encoder_funcs ` and :c:type:`struct -drm_connector_funcs ` structures with -pointers to the mid-layer top API functions. Installing the mid-layer -bottom operation handlers is best done right after registering the -corresponding KMS object. - -The mid-layer is not split between CRTC, encoder and connector -operations. To use it, a driver must provide bottom functions for all of -the three KMS entities. - -Atomic Modeset Helper Functions Reference ------------------------------------------ - -Overview -^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :doc: overview - -Implementing Asynchronous Atomic Commit -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :doc: implementing nonblocking commit - -Atomic State Reset and Initialization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :doc: atomic state reset and initialization - -.. kernel-doc:: include/drm/drm_atomic_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c - :export: - -Modeset Helper Reference for Common Vtables -------------------------------------------- - -.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h - :internal: - -.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h - :doc: overview - -Legacy CRTC/Modeset Helper Functions Reference ----------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c - :doc: overview - -Output Probing Helper Functions Reference ------------------------------------------ - -.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c - :doc: output probing helper overview - -.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c - :export: - -fbdev Helper Functions Reference --------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c - :doc: fbdev helpers - -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c - :export: - -.. kernel-doc:: include/drm/drm_fb_helper.h - :internal: - -Framebuffer CMA Helper Functions Reference ------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c - :doc: framebuffer cma helper functions - -.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c - :export: - -Display Port Helper Functions Reference ---------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c - :doc: dp helpers - -.. kernel-doc:: include/drm/drm_dp_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c - :export: - -Display Port Dual Mode Adaptor Helper Functions Reference ---------------------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c - :doc: dp dual mode helpers - -.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c - :export: - -Display Port MST Helper Functions Reference -------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c - :doc: dp mst helper - -.. kernel-doc:: include/drm/drm_dp_mst_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c - :export: - -MIPI DSI Helper Functions Reference ------------------------------------ - -.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c - :doc: dsi helpers - -.. kernel-doc:: include/drm/drm_mipi_dsi.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c - :export: - -EDID Helper Functions Reference -------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_edid.c - :export: - -Rectangle Utilities Reference ------------------------------ - -.. kernel-doc:: include/drm/drm_rect.h - :doc: rect utils - -.. kernel-doc:: include/drm/drm_rect.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_rect.c - :export: - -Flip-work Helper Reference --------------------------- - -.. kernel-doc:: include/drm/drm_flip_work.h - :doc: flip utils - -.. kernel-doc:: include/drm/drm_flip_work.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_flip_work.c - :export: - -HDMI Infoframes Helper Reference --------------------------------- - -Strictly speaking this is not a DRM helper library but generally useable -by any driver interfacing with HDMI outputs like v4l or alsa drivers. -But it nicely fits into the overall topic of mode setting helper -libraries and hence is also included here. - -.. kernel-doc:: include/linux/hdmi.h - :internal: - -.. kernel-doc:: drivers/video/hdmi.c - :export: - -Plane Helper Reference ----------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c - :doc: overview - -Tile group ----------- - -.. kernel-doc:: drivers/gpu/drm/drm_crtc.c - :doc: Tile group - -Bridges -------- - -Overview -^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_bridge.c - :doc: overview - -Default bridge callback sequence -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. kernel-doc:: drivers/gpu/drm/drm_bridge.c - :doc: bridge callbacks - -.. kernel-doc:: drivers/gpu/drm/drm_bridge.c - :export: - -Panel Helper Reference ----------------------- - -.. kernel-doc:: include/drm/drm_panel.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_panel.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_panel.c - :doc: drm panel - -Simple KMS Helper Reference ---------------------------- - -.. kernel-doc:: include/drm/drm_simple_kms_helper.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c - :doc: overview - -KMS Properties -============== - -Drivers may need to expose additional parameters to applications than -those described in the previous sections. KMS supports attaching -properties to CRTCs, connectors and planes and offers a userspace API to -list, get and set the property values. - -Properties are identified by a name that uniquely defines the property -purpose, and store an associated value. For all property types except -blob properties the value is a 64-bit unsigned integer. - -KMS differentiates between properties and property instances. Drivers -first create properties and then create and associate individual -instances of those properties to objects. A property can be instantiated -multiple times and associated with different objects. Values are stored -in property instances, and all other property information are stored in -the property and shared between all instances of the property. - -Every property is created with a type that influences how the KMS core -handles the property. Supported property types are - -DRM_MODE_PROP_RANGE - Range properties report their minimum and maximum admissible values. - The KMS core verifies that values set by application fit in that - range. - -DRM_MODE_PROP_ENUM - Enumerated properties take a numerical value that ranges from 0 to - the number of enumerated values defined by the property minus one, - and associate a free-formed string name to each value. Applications - can retrieve the list of defined value-name pairs and use the - numerical value to get and set property instance values. - -DRM_MODE_PROP_BITMASK - Bitmask properties are enumeration properties that additionally - restrict all enumerated values to the 0..63 range. Bitmask property - instance values combine one or more of the enumerated bits defined - by the property. - -DRM_MODE_PROP_BLOB - Blob properties store a binary blob without any format restriction. - The binary blobs are created as KMS standalone objects, and blob - property instance values store the ID of their associated blob - object. - - Blob properties are only used for the connector EDID property and - cannot be created by drivers. - -To create a property drivers call one of the following functions -depending on the property type. All property creation functions take -property flags and name, as well as type-specific arguments. - -- struct drm_property \*drm_property_create_range(struct - drm_device \*dev, int flags, const char \*name, uint64_t min, - uint64_t max); - Create a range property with the given minimum and maximum values. - -- struct drm_property \*drm_property_create_enum(struct drm_device - \*dev, int flags, const char \*name, const struct - drm_prop_enum_list \*props, int num_values); - Create an enumerated property. The ``props`` argument points to an - array of ``num_values`` value-name pairs. - -- struct drm_property \*drm_property_create_bitmask(struct - drm_device \*dev, int flags, const char \*name, const struct - drm_prop_enum_list \*props, int num_values); - Create a bitmask property. The ``props`` argument points to an array - of ``num_values`` value-name pairs. - -Properties can additionally be created as immutable, in which case they -will be read-only for applications but can be modified by the driver. To -create an immutable property drivers must set the -DRM_MODE_PROP_IMMUTABLE flag at property creation time. - -When no array of value-name pairs is readily available at property -creation time for enumerated or range properties, drivers can create the -property using the :c:func:`drm_property_create()` function and -manually add enumeration value-name pairs by calling the -:c:func:`drm_property_add_enum()` function. Care must be taken to -properly specify the property type through the ``flags`` argument. - -After creating properties drivers can attach property instances to CRTC, -connector and plane objects by calling the -:c:func:`drm_object_attach_property()`. The function takes a -pointer to the target object, a pointer to the previously created -property and an initial instance value. - -Existing KMS Properties ------------------------ - -The following table gives description of drm properties exposed by -various modules/drivers. - -.. csv-table:: - :header-rows: 1 - :file: kms-properties.csv - -Vertical Blanking -================= - -Vertical blanking plays a major role in graphics rendering. To achieve -tear-free display, users must synchronize page flips and/or rendering to -vertical blanking. The DRM API offers ioctls to perform page flips -synchronized to vertical blanking and wait for vertical blanking. - -The DRM core handles most of the vertical blanking management logic, -which involves filtering out spurious interrupts, keeping race-free -blanking counters, coping with counter wrap-around and resets and -keeping use counts. It relies on the driver to generate vertical -blanking interrupts and optionally provide a hardware vertical blanking -counter. Drivers must implement the following operations. - -- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void - (\*disable_vblank) (struct drm_device \*dev, int crtc); - Enable or disable vertical blanking interrupts for the given CRTC. - -- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); - Retrieve the value of the vertical blanking counter for the given - CRTC. If the hardware maintains a vertical blanking counter its value - should be returned. Otherwise drivers can use the - :c:func:`drm_vblank_count()` helper function to handle this - operation. - -Drivers must initialize the vertical blanking handling core with a call -to :c:func:`drm_vblank_init()` in their load operation. - -Vertical blanking interrupts can be enabled by the DRM core or by -drivers themselves (for instance to handle page flipping operations). -The DRM core maintains a vertical blanking use count to ensure that the -interrupts are not disabled while a user still needs them. To increment -the use count, drivers call :c:func:`drm_vblank_get()`. Upon -return vertical blanking interrupts are guaranteed to be enabled. - -To decrement the use count drivers call -:c:func:`drm_vblank_put()`. Only when the use count drops to zero -will the DRM core disable the vertical blanking interrupts after a delay -by scheduling a timer. The delay is accessible through the -vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global -variable and expressed in milliseconds. Its default value is 5000 ms. -Zero means never disable, and a negative value means disable -immediately. Drivers may override the behaviour by setting the -:c:type:`struct drm_device ` -vblank_disable_immediate flag, which when set causes vblank interrupts -to be disabled immediately regardless of the drm_vblank_offdelay -value. The flag should only be set if there's a properly working -hardware vblank counter present. - -When a vertical blanking interrupt occurs drivers only need to call the -:c:func:`drm_handle_vblank()` function to account for the -interrupt. - -Resources allocated by :c:func:`drm_vblank_init()` must be freed -with a call to :c:func:`drm_vblank_cleanup()` in the driver unload -operation handler. - -Vertical Blanking and Interrupt Handling Functions Reference ------------------------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_irq.c - :export: - -.. kernel-doc:: include/drm/drmP.h - :functions: drm_crtc_vblank_waitqueue - Open/Close, File Operations and IOCTLs ====================================== diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst new file mode 100644 index 000000000000..0b302fedf1af --- /dev/null +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -0,0 +1,260 @@ +============================= +Mode Setting Helper Functions +============================= + +The plane, CRTC, encoder and connector functions provided by the drivers +implement the DRM API. They're called by the DRM core and ioctl handlers +to handle device state changes and configuration request. As +implementing those functions often requires logic not specific to +drivers, mid-layer helper functions are available to avoid duplicating +boilerplate code. + +The DRM core contains one mid-layer implementation. The mid-layer +provides implementations of several plane, CRTC, encoder and connector +functions (called from the top of the mid-layer) that pre-process +requests and call lower-level functions provided by the driver (at the +bottom of the mid-layer). For instance, the +:c:func:`drm_crtc_helper_set_config()` function can be used to +fill the :c:type:`struct drm_crtc_funcs ` +set_config field. When called, it will split the set_config operation +in smaller, simpler operations and call the driver to handle them. + +To use the mid-layer, drivers call +:c:func:`drm_crtc_helper_add()`, +:c:func:`drm_encoder_helper_add()` and +:c:func:`drm_connector_helper_add()` functions to install their +mid-layer bottom operations handlers, and fill the :c:type:`struct +drm_crtc_funcs `, :c:type:`struct +drm_encoder_funcs ` and :c:type:`struct +drm_connector_funcs ` structures with +pointers to the mid-layer top API functions. Installing the mid-layer +bottom operation handlers is best done right after registering the +corresponding KMS object. + +The mid-layer is not split between CRTC, encoder and connector +operations. To use it, a driver must provide bottom functions for all of +the three KMS entities. + +Atomic Modeset Helper Functions Reference +========================================= + +Overview +-------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: overview + +Implementing Asynchronous Atomic Commit +--------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: implementing nonblocking commit + +Atomic State Reset and Initialization +------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :doc: atomic state reset and initialization + +.. kernel-doc:: include/drm/drm_atomic_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c + :export: + +Modeset Helper Reference for Common Vtables +=========================================== + +.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h + :internal: + +.. kernel-doc:: include/drm/drm_modeset_helper_vtables.h + :doc: overview + +Legacy CRTC/Modeset Helper Functions Reference +============================================== + +.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c + :doc: overview + +Output Probing Helper Functions Reference +========================================= + +.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c + :doc: output probing helper overview + +.. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c + :export: + +fbdev Helper Functions Reference +================================ + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :doc: fbdev helpers + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :export: + +.. kernel-doc:: include/drm/drm_fb_helper.h + :internal: + +Framebuffer CMA Helper Functions Reference +========================================== + +.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c + :doc: framebuffer cma helper functions + +.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c + :export: + +Display Port Helper Functions Reference +======================================= + +.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c + :doc: dp helpers + +.. kernel-doc:: include/drm/drm_dp_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c + :export: + +Display Port Dual Mode Adaptor Helper Functions Reference +========================================================= + +.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c + :doc: dp dual mode helpers + +.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c + :export: + +Display Port MST Helper Functions Reference +=========================================== + +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c + :doc: dp mst helper + +.. kernel-doc:: include/drm/drm_dp_mst_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c + :export: + +MIPI DSI Helper Functions Reference +=================================== + +.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c + :doc: dsi helpers + +.. kernel-doc:: include/drm/drm_mipi_dsi.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c + :export: + +EDID Helper Functions Reference +=============================== + +.. kernel-doc:: drivers/gpu/drm/drm_edid.c + :export: + +Rectangle Utilities Reference +============================= + +.. kernel-doc:: include/drm/drm_rect.h + :doc: rect utils + +.. kernel-doc:: include/drm/drm_rect.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_rect.c + :export: + +Flip-work Helper Reference +========================== + +.. kernel-doc:: include/drm/drm_flip_work.h + :doc: flip utils + +.. kernel-doc:: include/drm/drm_flip_work.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_flip_work.c + :export: + +HDMI Infoframes Helper Reference +================================ + +Strictly speaking this is not a DRM helper library but generally useable +by any driver interfacing with HDMI outputs like v4l or alsa drivers. +But it nicely fits into the overall topic of mode setting helper +libraries and hence is also included here. + +.. kernel-doc:: include/linux/hdmi.h + :internal: + +.. kernel-doc:: drivers/video/hdmi.c + :export: + +Plane Helper Reference +====================== + +.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c + :doc: overview + +Tile group +---------- + +.. kernel-doc:: drivers/gpu/drm/drm_crtc.c + :doc: Tile group + +Bridges +======= + +Overview +-------- + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: overview + +Default bridge callback sequence +-------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :doc: bridge callbacks + +.. kernel-doc:: drivers/gpu/drm/drm_bridge.c + :export: + +Panel Helper Reference +====================== + +.. kernel-doc:: include/drm/drm_panel.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_panel.c + :doc: drm panel + +Simple KMS Helper Reference +=========================== + +.. kernel-doc:: include/drm/drm_simple_kms_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_simple_kms_helper.c + :doc: overview diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst new file mode 100644 index 000000000000..0e1c80436c1d --- /dev/null +++ b/Documentation/gpu/drm-kms.rst @@ -0,0 +1,656 @@ +========================= +Kernel Mode Setting (KMS) +========================= + +Mode Setting +============ + +Drivers must initialize the mode setting core by calling +:c:func:`drm_mode_config_init()` on the DRM device. The function +initializes the :c:type:`struct drm_device ` +mode_config field and never fails. Once done, mode configuration must +be setup by initializing the following fields. + +- int min_width, min_height; int max_width, max_height; + Minimum and maximum width and height of the frame buffers in pixel + units. + +- struct drm_mode_config_funcs \*funcs; + Mode setting functions. + +Display Modes Function Reference +-------------------------------- + +.. kernel-doc:: include/drm/drm_modes.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_modes.c + :export: + +Atomic Mode Setting Function Reference +-------------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :internal: + +Frame Buffer Abstraction +------------------------ + +Frame buffers are abstract memory objects that provide a source of +pixels to scanout to a CRTC. Applications explicitly request the +creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls +and receive an opaque handle that can be passed to the KMS CRTC control, +plane configuration and page flip functions. + +Frame buffers rely on the underneath memory manager for low-level memory +operations. When creating a frame buffer applications pass a memory +handle (or a list of memory handles for multi-planar formats) through +the ``drm_mode_fb_cmd2`` argument. For drivers using GEM as their +userspace buffer management interface this would be a GEM handle. +Drivers are however free to use their own backing storage object +handles, e.g. vmwgfx directly exposes special TTM handles to userspace +and so expects TTM handles in the create ioctl and not GEM handles. + +The lifetime of a drm framebuffer is controlled with a reference count, +drivers can grab additional references with +:c:func:`drm_framebuffer_reference()`and drop them again with +:c:func:`drm_framebuffer_unreference()`. For driver-private +framebuffers for which the last reference is never dropped (e.g. for the +fbdev framebuffer when the struct :c:type:`struct drm_framebuffer +` is embedded into the fbdev helper struct) +drivers can manually clean up a framebuffer at module unload time with +:c:func:`drm_framebuffer_unregister_private()`. + +DRM Format Handling +------------------- + +.. kernel-doc:: include/drm/drm_fourcc.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c + :export: + +Dumb Buffer Objects +------------------- + +The KMS API doesn't standardize backing storage object creation and +leaves it to driver-specific ioctls. Furthermore actually creating a +buffer object even for GEM-based drivers is done through a +driver-specific ioctl - GEM only has a common userspace interface for +sharing and destroying objects. While not an issue for full-fledged +graphics stacks that include device-specific userspace components (in +libdrm for instance), this limit makes DRM-based early boot graphics +unnecessarily complex. + +Dumb objects partly alleviate the problem by providing a standard API to +create dumb buffers suitable for scanout, which can then be used to +create KMS frame buffers. + +To support dumb objects drivers must implement the dumb_create, +dumb_destroy and dumb_map_offset operations. + +- int (\*dumb_create)(struct drm_file \*file_priv, struct + drm_device \*dev, struct drm_mode_create_dumb \*args); + The dumb_create operation creates a driver object (GEM or TTM + handle) suitable for scanout based on the width, height and depth + from the struct :c:type:`struct drm_mode_create_dumb + ` argument. It fills the argument's + handle, pitch and size fields with a handle for the newly created + object and its line pitch and size in bytes. + +- int (\*dumb_destroy)(struct drm_file \*file_priv, struct + drm_device \*dev, uint32_t handle); + The dumb_destroy operation destroys a dumb object created by + dumb_create. + +- int (\*dumb_map_offset)(struct drm_file \*file_priv, struct + drm_device \*dev, uint32_t handle, uint64_t \*offset); + The dumb_map_offset operation associates an mmap fake offset with + the object given by the handle and returns it. Drivers must use the + :c:func:`drm_gem_create_mmap_offset()` function to associate + the fake offset as described in ?. + +Note that dumb objects may not be used for gpu acceleration, as has been +attempted on some ARM embedded platforms. Such drivers really must have +a hardware-specific ioctl to allocate suitable buffer objects. + +Output Polling +-------------- + +void (\*output_poll_changed)(struct drm_device \*dev); +This operation notifies the driver that the status of one or more +connectors has changed. Drivers that use the fb helper can just call the +:c:func:`drm_fb_helper_hotplug_event()` function to handle this +operation. + +KMS Initialization and Cleanup +============================== + +A KMS device is abstracted and exposed as a set of planes, CRTCs, +encoders and connectors. KMS drivers must thus create and initialize all +those objects at load time after initializing mode setting. + +CRTCs (:c:type:`struct drm_crtc `) +-------------------------------------------- + +A CRTC is an abstraction representing a part of the chip that contains a +pointer to a scanout buffer. Therefore, the number of CRTCs available +determines how many independent scanout buffers can be active at any +given time. The CRTC structure contains several fields to support this: +a pointer to some video memory (abstracted as a frame buffer object), a +display mode, and an (x, y) offset into the video memory to support +panning or configurations where one piece of video memory spans multiple +CRTCs. + +CRTC Initialization +~~~~~~~~~~~~~~~~~~~ + +A KMS device must create and register at least one struct +:c:type:`struct drm_crtc ` instance. The instance is +allocated and zeroed by the driver, possibly as part of a larger +structure, and registered with a call to :c:func:`drm_crtc_init()` +with a pointer to CRTC functions. + +Planes (:c:type:`struct drm_plane `) +----------------------------------------------- + +A plane represents an image source that can be blended with or overlayed +on top of a CRTC during the scanout process. Planes are associated with +a frame buffer to crop a portion of the image memory (source) and +optionally scale it to a destination size. The result is then blended +with or overlayed on top of a CRTC. + +The DRM core recognizes three types of planes: + +- DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. + Primary planes are the planes operated upon by CRTC modesetting and + flipping operations described in the page_flip hook in + :c:type:`struct drm_crtc_funcs `. +- DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. + Cursor planes are the planes operated upon by the + DRM_IOCTL_MODE_CURSOR and DRM_IOCTL_MODE_CURSOR2 ioctls. +- DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor + planes. Some drivers refer to these types of planes as "sprites" + internally. + +For compatibility with legacy userspace, only overlay planes are made +available to userspace by default. Userspace clients may set the +DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate +that they wish to receive a universal plane list containing all plane +types. + +Plane Initialization +~~~~~~~~~~~~~~~~~~~~ + +To create a plane, a KMS drivers allocates and zeroes an instances of +:c:type:`struct drm_plane ` (possibly as part of a +larger structure) and registers it with a call to +:c:func:`drm_universal_plane_init()`. The function takes a +bitmask of the CRTCs that can be associated with the plane, a pointer to +the plane functions, a list of format supported formats, and the type of +plane (primary, cursor, or overlay) being initialized. + +Cursor and overlay planes are optional. All drivers should provide one +primary plane per CRTC (although this requirement may change in the +future); drivers that do not wish to provide special handling for +primary planes may make use of the helper functions described in ? to +create and register a primary plane with standard capabilities. + +Encoders (:c:type:`struct drm_encoder `) +----------------------------------------------------- + +An encoder takes pixel data from a CRTC and converts it to a format +suitable for any attached connectors. On some devices, it may be +possible to have a CRTC send data to more than one encoder. In that +case, both encoders would receive data from the same scanout buffer, +resulting in a "cloned" display configuration across the connectors +attached to each encoder. + +Encoder Initialization +~~~~~~~~~~~~~~~~~~~~~~ + +As for CRTCs, a KMS driver must create, initialize and register at least +one :c:type:`struct drm_encoder ` instance. The +instance is allocated and zeroed by the driver, possibly as part of a +larger structure. + +Drivers must initialize the :c:type:`struct drm_encoder +` possible_crtcs and possible_clones fields before +registering the encoder. Both fields are bitmasks of respectively the +CRTCs that the encoder can be connected to, and sibling encoders +candidate for cloning. + +After being initialized, the encoder must be registered with a call to +:c:func:`drm_encoder_init()`. The function takes a pointer to the +encoder functions and an encoder type. Supported types are + +- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A +- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort +- DRM_MODE_ENCODER_LVDS for display panels +- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, + Component, SCART) +- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays + +Encoders must be attached to a CRTC to be used. DRM drivers leave +encoders unattached at initialization time. Applications (or the fbdev +compatibility layer when implemented) are responsible for attaching the +encoders they want to use to a CRTC. + +Connectors (:c:type:`struct drm_connector `) +----------------------------------------------------------- + +A connector is the final destination for pixel data on a device, and +usually connects directly to an external display device like a monitor +or laptop panel. A connector can only be attached to one encoder at a +time. The connector is also the structure where information about the +attached display is kept, so it contains fields for display data, EDID +data, DPMS & connection status, and information about modes supported on +the attached displays. + +Connector Initialization +~~~~~~~~~~~~~~~~~~~~~~~~ + +Finally a KMS driver must create, initialize, register and attach at +least one :c:type:`struct drm_connector ` +instance. The instance is created as other KMS objects and initialized +by setting the following fields. + +interlace_allowed + Whether the connector can handle interlaced modes. + +doublescan_allowed + Whether the connector can handle doublescan. + +display_info + Display information is filled from EDID information when a display + is detected. For non hot-pluggable displays such as flat panels in + embedded systems, the driver should initialize the + display_info.width_mm and display_info.height_mm fields with the + physical size of the display. + +polled + Connector polling mode, a combination of + + DRM_CONNECTOR_POLL_HPD + The connector generates hotplug events and doesn't need to be + periodically polled. The CONNECT and DISCONNECT flags must not + be set together with the HPD flag. + + DRM_CONNECTOR_POLL_CONNECT + Periodically poll the connector for connection. + + DRM_CONNECTOR_POLL_DISCONNECT + Periodically poll the connector for disconnection. + + Set to 0 for connectors that don't support connection status + discovery. + +The connector is then registered with a call to +:c:func:`drm_connector_init()` with a pointer to the connector +functions and a connector type, and exposed through sysfs with a call to +:c:func:`drm_connector_register()`. + +Supported connector types are + +- DRM_MODE_CONNECTOR_VGA +- DRM_MODE_CONNECTOR_DVII +- DRM_MODE_CONNECTOR_DVID +- DRM_MODE_CONNECTOR_DVIA +- DRM_MODE_CONNECTOR_Composite +- DRM_MODE_CONNECTOR_SVIDEO +- DRM_MODE_CONNECTOR_LVDS +- DRM_MODE_CONNECTOR_Component +- DRM_MODE_CONNECTOR_9PinDIN +- DRM_MODE_CONNECTOR_DisplayPort +- DRM_MODE_CONNECTOR_HDMIA +- DRM_MODE_CONNECTOR_HDMIB +- DRM_MODE_CONNECTOR_TV +- DRM_MODE_CONNECTOR_eDP +- DRM_MODE_CONNECTOR_VIRTUAL + +Connectors must be attached to an encoder to be used. For devices that +map connectors to encoders 1:1, the connector should be attached at +initialization time with a call to +:c:func:`drm_mode_connector_attach_encoder()`. The driver must +also set the :c:type:`struct drm_connector ` +encoder field to point to the attached encoder. + +Finally, drivers must initialize the connectors state change detection +with a call to :c:func:`drm_kms_helper_poll_init()`. If at least +one connector is pollable but can't generate hotplug interrupts +(indicated by the DRM_CONNECTOR_POLL_CONNECT and +DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will +automatically be queued to periodically poll for changes. Connectors +that can generate hotplug interrupts must be marked with the +DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must +call :c:func:`drm_helper_hpd_irq_event()`. The function will +queue a delayed work to check the state of all connectors, but no +periodic polling will be done. + +Connector Operations +~~~~~~~~~~~~~~~~~~~~ + + **Note** + + Unless otherwise state, all operations are mandatory. + +DPMS +'''' + +void (\*dpms)(struct drm_connector \*connector, int mode); +The DPMS operation sets the power state of a connector. The mode +argument is one of + +- DRM_MODE_DPMS_ON + +- DRM_MODE_DPMS_STANDBY + +- DRM_MODE_DPMS_SUSPEND + +- DRM_MODE_DPMS_OFF + +In all but DPMS_ON mode the encoder to which the connector is attached +should put the display in low-power mode by driving its signals +appropriately. If more than one connector is attached to the encoder +care should be taken not to change the power state of other displays as +a side effect. Low-power mode should be propagated to the encoders and +CRTCs when all related connectors are put in low-power mode. + +Modes +''''' + +int (\*fill_modes)(struct drm_connector \*connector, uint32_t +max_width, uint32_t max_height); +Fill the mode list with all supported modes for the connector. If the +``max_width`` and ``max_height`` arguments are non-zero, the +implementation must ignore all modes wider than ``max_width`` or higher +than ``max_height``. + +The connector must also fill in this operation its display_info +width_mm and height_mm fields with the connected display physical size +in millimeters. The fields should be set to 0 if the value isn't known +or is not applicable (for instance for projector devices). + +Connection Status +''''''''''''''''' + +The connection status is updated through polling or hotplug events when +supported (see ?). The status value is reported to userspace through +ioctls and must not be used inside the driver, as it only gets +initialized by a call to :c:func:`drm_mode_getconnector()` from +userspace. + +enum drm_connector_status (\*detect)(struct drm_connector +\*connector, bool force); +Check to see if anything is attached to the connector. The ``force`` +parameter is set to false whilst polling or to true when checking the +connector due to user request. ``force`` can be used by the driver to +avoid expensive, destructive operations during automated probing. + +Return connector_status_connected if something is connected to the +connector, connector_status_disconnected if nothing is connected and +connector_status_unknown if the connection state isn't known. + +Drivers should only return connector_status_connected if the +connection status has really been probed as connected. Connectors that +can't detect the connection status, or failed connection status probes, +should return connector_status_unknown. + +Cleanup +------- + +The DRM core manages its objects' lifetime. When an object is not needed +anymore the core calls its destroy function, which must clean up and +free every resource allocated for the object. Every +:c:func:`drm_\*_init()` call must be matched with a corresponding +:c:func:`drm_\*_cleanup()` call to cleanup CRTCs +(:c:func:`drm_crtc_cleanup()`), planes +(:c:func:`drm_plane_cleanup()`), encoders +(:c:func:`drm_encoder_cleanup()`) and connectors +(:c:func:`drm_connector_cleanup()`). Furthermore, connectors that +have been added to sysfs must be removed by a call to +:c:func:`drm_connector_unregister()` before calling +:c:func:`drm_connector_cleanup()`. + +Connectors state change detection must be cleanup up with a call to +:c:func:`drm_kms_helper_poll_fini()`. + +Output discovery and initialization example +------------------------------------------- + +:: + + void intel_crt_init(struct drm_device *dev) + { + struct drm_connector *connector; + struct intel_output *intel_output; + + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) + return; + + connector = &intel_output->base; + drm_connector_init(dev, &intel_output->base, + &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); + + drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, + DRM_MODE_ENCODER_DAC); + + drm_mode_connector_attach_encoder(&intel_output->base, + &intel_output->enc); + + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } + + intel_output->type = INTEL_OUTPUT_ANALOG; + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); + drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); + + drm_connector_register(connector); + } + +In the example above (taken from the i915 driver), a CRTC, connector and +encoder combination is created. A device-specific i2c bus is also +created for fetching EDID data and performing monitor detection. Once +the process is complete, the new connector is registered with sysfs to +make its properties available to applications. + +KMS API Functions +----------------- + +.. kernel-doc:: drivers/gpu/drm/drm_crtc.c + :export: + +KMS Data Structures +------------------- + +.. kernel-doc:: include/drm/drm_crtc.h + :internal: + +KMS Locking +----------- + +.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c + :doc: kms locking + +.. kernel-doc:: include/drm/drm_modeset_lock.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c + :export: + +KMS Properties +============== + +Drivers may need to expose additional parameters to applications than +those described in the previous sections. KMS supports attaching +properties to CRTCs, connectors and planes and offers a userspace API to +list, get and set the property values. + +Properties are identified by a name that uniquely defines the property +purpose, and store an associated value. For all property types except +blob properties the value is a 64-bit unsigned integer. + +KMS differentiates between properties and property instances. Drivers +first create properties and then create and associate individual +instances of those properties to objects. A property can be instantiated +multiple times and associated with different objects. Values are stored +in property instances, and all other property information are stored in +the property and shared between all instances of the property. + +Every property is created with a type that influences how the KMS core +handles the property. Supported property types are + +DRM_MODE_PROP_RANGE + Range properties report their minimum and maximum admissible values. + The KMS core verifies that values set by application fit in that + range. + +DRM_MODE_PROP_ENUM + Enumerated properties take a numerical value that ranges from 0 to + the number of enumerated values defined by the property minus one, + and associate a free-formed string name to each value. Applications + can retrieve the list of defined value-name pairs and use the + numerical value to get and set property instance values. + +DRM_MODE_PROP_BITMASK + Bitmask properties are enumeration properties that additionally + restrict all enumerated values to the 0..63 range. Bitmask property + instance values combine one or more of the enumerated bits defined + by the property. + +DRM_MODE_PROP_BLOB + Blob properties store a binary blob without any format restriction. + The binary blobs are created as KMS standalone objects, and blob + property instance values store the ID of their associated blob + object. + + Blob properties are only used for the connector EDID property and + cannot be created by drivers. + +To create a property drivers call one of the following functions +depending on the property type. All property creation functions take +property flags and name, as well as type-specific arguments. + +- struct drm_property \*drm_property_create_range(struct + drm_device \*dev, int flags, const char \*name, uint64_t min, + uint64_t max); + Create a range property with the given minimum and maximum values. + +- struct drm_property \*drm_property_create_enum(struct drm_device + \*dev, int flags, const char \*name, const struct + drm_prop_enum_list \*props, int num_values); + Create an enumerated property. The ``props`` argument points to an + array of ``num_values`` value-name pairs. + +- struct drm_property \*drm_property_create_bitmask(struct + drm_device \*dev, int flags, const char \*name, const struct + drm_prop_enum_list \*props, int num_values); + Create a bitmask property. The ``props`` argument points to an array + of ``num_values`` value-name pairs. + +Properties can additionally be created as immutable, in which case they +will be read-only for applications but can be modified by the driver. To +create an immutable property drivers must set the +DRM_MODE_PROP_IMMUTABLE flag at property creation time. + +When no array of value-name pairs is readily available at property +creation time for enumerated or range properties, drivers can create the +property using the :c:func:`drm_property_create()` function and +manually add enumeration value-name pairs by calling the +:c:func:`drm_property_add_enum()` function. Care must be taken to +properly specify the property type through the ``flags`` argument. + +After creating properties drivers can attach property instances to CRTC, +connector and plane objects by calling the +:c:func:`drm_object_attach_property()`. The function takes a +pointer to the target object, a pointer to the previously created +property and an initial instance value. + +Existing KMS Properties +----------------------- + +The following table gives description of drm properties exposed by +various modules/drivers. + +.. csv-table:: + :header-rows: 1 + :file: kms-properties.csv + +Vertical Blanking +================= + +Vertical blanking plays a major role in graphics rendering. To achieve +tear-free display, users must synchronize page flips and/or rendering to +vertical blanking. The DRM API offers ioctls to perform page flips +synchronized to vertical blanking and wait for vertical blanking. + +The DRM core handles most of the vertical blanking management logic, +which involves filtering out spurious interrupts, keeping race-free +blanking counters, coping with counter wrap-around and resets and +keeping use counts. It relies on the driver to generate vertical +blanking interrupts and optionally provide a hardware vertical blanking +counter. Drivers must implement the following operations. + +- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void + (\*disable_vblank) (struct drm_device \*dev, int crtc); + Enable or disable vertical blanking interrupts for the given CRTC. + +- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); + Retrieve the value of the vertical blanking counter for the given + CRTC. If the hardware maintains a vertical blanking counter its value + should be returned. Otherwise drivers can use the + :c:func:`drm_vblank_count()` helper function to handle this + operation. + +Drivers must initialize the vertical blanking handling core with a call +to :c:func:`drm_vblank_init()` in their load operation. + +Vertical blanking interrupts can be enabled by the DRM core or by +drivers themselves (for instance to handle page flipping operations). +The DRM core maintains a vertical blanking use count to ensure that the +interrupts are not disabled while a user still needs them. To increment +the use count, drivers call :c:func:`drm_vblank_get()`. Upon +return vertical blanking interrupts are guaranteed to be enabled. + +To decrement the use count drivers call +:c:func:`drm_vblank_put()`. Only when the use count drops to zero +will the DRM core disable the vertical blanking interrupts after a delay +by scheduling a timer. The delay is accessible through the +vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global +variable and expressed in milliseconds. Its default value is 5000 ms. +Zero means never disable, and a negative value means disable +immediately. Drivers may override the behaviour by setting the +:c:type:`struct drm_device ` +vblank_disable_immediate flag, which when set causes vblank interrupts +to be disabled immediately regardless of the drm_vblank_offdelay +value. The flag should only be set if there's a properly working +hardware vblank counter present. + +When a vertical blanking interrupt occurs drivers only need to call the +:c:func:`drm_handle_vblank()` function to account for the +interrupt. + +Resources allocated by :c:func:`drm_vblank_init()` must be freed +with a call to :c:func:`drm_vblank_cleanup()` in the driver unload +operation handler. + +Vertical Blanking and Interrupt Handling Functions Reference +------------------------------------------------------------ + +.. kernel-doc:: drivers/gpu/drm/drm_irq.c + :export: + +.. kernel-doc:: include/drm/drmP.h + :functions: drm_crtc_vblank_waitqueue diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst new file mode 100644 index 000000000000..59f9822fecd0 --- /dev/null +++ b/Documentation/gpu/drm-mm.rst @@ -0,0 +1,454 @@ +===================== +DRM Memory Management +===================== + +Modern Linux systems require large amount of graphics memory to store +frame buffers, textures, vertices and other graphics-related data. Given +the very dynamic nature of many of that data, managing graphics memory +efficiently is thus crucial for the graphics stack and plays a central +role in the DRM infrastructure. + +The DRM core includes two memory managers, namely Translation Table Maps +(TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory +manager to be developed and tried to be a one-size-fits-them all +solution. It provides a single userspace API to accommodate the need of +all hardware, supporting both Unified Memory Architecture (UMA) devices +and devices with dedicated video RAM (i.e. most discrete video cards). +This resulted in a large, complex piece of code that turned out to be +hard to use for driver development. + +GEM started as an Intel-sponsored project in reaction to TTM's +complexity. Its design philosophy is completely different: instead of +providing a solution to every graphics memory-related problems, GEM +identified common code between drivers and created a support library to +share it. GEM has simpler initialization and execution requirements than +TTM, but has no video RAM management capabilities and is thus limited to +UMA devices. + +The Translation Table Manager (TTM) +----------------------------------- + +TTM design background and information belongs here. + +TTM initialization +~~~~~~~~~~~~~~~~~~ + + **Warning** + + This section is outdated. + +Drivers wishing to support TTM must fill out a drm_bo_driver +structure. The structure contains several fields with function pointers +for initializing the TTM, allocating and freeing memory, waiting for +command completion and fence synchronization, and memory migration. See +the radeon_ttm.c file for an example of usage. + +The ttm_global_reference structure is made up of several fields: + +:: + + struct ttm_global_reference { + enum ttm_global_types global_type; + size_t size; + void *object; + int (*init) (struct ttm_global_reference *); + void (*release) (struct ttm_global_reference *); + }; + + +There should be one global reference structure for your memory manager +as a whole, and there will be others for each object created by the +memory manager at runtime. Your global TTM should have a type of +TTM_GLOBAL_TTM_MEM. The size field for the global object should be +sizeof(struct ttm_mem_global), and the init and release hooks should +point at your driver-specific init and release routines, which probably +eventually call ttm_mem_global_init and ttm_mem_global_release, +respectively. + +Once your global TTM accounting structure is set up and initialized by +calling ttm_global_item_ref() on it, you need to create a buffer +object TTM to provide a pool for buffer object allocation by clients and +the kernel itself. The type of this object should be +TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct +ttm_bo_global). Again, driver-specific init and release functions may +be provided, likely eventually calling ttm_bo_global_init() and +ttm_bo_global_release(), respectively. Also, like the previous +object, ttm_global_item_ref() is used to create an initial reference +count for the TTM, which will call your initialization function. + +The Graphics Execution Manager (GEM) +------------------------------------ + +The GEM design approach has resulted in a memory manager that doesn't +provide full coverage of all (or even all common) use cases in its +userspace or kernel API. GEM exposes a set of standard memory-related +operations to userspace and a set of helper functions to drivers, and +let drivers implement hardware-specific operations with their own +private API. + +The GEM userspace API is described in the `GEM - the Graphics Execution +Manager `__ article on LWN. While +slightly outdated, the document provides a good overview of the GEM API +principles. Buffer allocation and read and write operations, described +as part of the common GEM API, are currently implemented using +driver-specific ioctls. + +GEM is data-agnostic. It manages abstract buffer objects without knowing +what individual buffers contain. APIs that require knowledge of buffer +contents or purpose, such as buffer allocation or synchronization +primitives, are thus outside of the scope of GEM and must be implemented +using driver-specific ioctls. + +On a fundamental level, GEM involves several operations: + +- Memory allocation and freeing +- Command execution +- Aperture management at command execution time + +Buffer object allocation is relatively straightforward and largely +provided by Linux's shmem layer, which provides memory to back each +object. + +Device-specific operations, such as command execution, pinning, buffer +read & write, mapping, and domain ownership transfers are left to +driver-specific ioctls. + +GEM Initialization +~~~~~~~~~~~~~~~~~~ + +Drivers that use GEM must set the DRIVER_GEM bit in the struct +:c:type:`struct drm_driver ` driver_features +field. The DRM core will then automatically initialize the GEM core +before calling the load operation. Behind the scene, this will create a +DRM Memory Manager object which provides an address space pool for +object allocation. + +In a KMS configuration, drivers need to allocate and initialize a +command ring buffer following core GEM initialization if required by the +hardware. UMA devices usually have what is called a "stolen" memory +region, which provides space for the initial framebuffer and large, +contiguous memory regions required by the device. This space is +typically not managed by GEM, and must be initialized separately into +its own DRM MM object. + +GEM Objects Creation +~~~~~~~~~~~~~~~~~~~~ + +GEM splits creation of GEM objects and allocation of the memory that +backs them in two distinct operations. + +GEM objects are represented by an instance of struct :c:type:`struct +drm_gem_object `. Drivers usually need to +extend GEM objects with private information and thus create a +driver-specific GEM object structure type that embeds an instance of +struct :c:type:`struct drm_gem_object `. + +To create a GEM object, a driver allocates memory for an instance of its +specific GEM object type and initializes the embedded struct +:c:type:`struct drm_gem_object ` with a call +to :c:func:`drm_gem_object_init()`. The function takes a pointer +to the DRM device, a pointer to the GEM object and the buffer object +size in bytes. + +GEM uses shmem to allocate anonymous pageable memory. +:c:func:`drm_gem_object_init()` will create an shmfs file of the +requested size and store it into the struct :c:type:`struct +drm_gem_object ` filp field. The memory is +used as either main storage for the object when the graphics hardware +uses system memory directly or as a backing store otherwise. + +Drivers are responsible for the actual physical pages allocation by +calling :c:func:`shmem_read_mapping_page_gfp()` for each page. +Note that they can decide to allocate pages when initializing the GEM +object, or to delay allocation until the memory is needed (for instance +when a page fault occurs as a result of a userspace memory access or +when the driver needs to start a DMA transfer involving the memory). + +Anonymous pageable memory allocation is not always desired, for instance +when the hardware requires physically contiguous system memory as is +often the case in embedded devices. Drivers can create GEM objects with +no shmfs backing (called private GEM objects) by initializing them with +a call to :c:func:`drm_gem_private_object_init()` instead of +:c:func:`drm_gem_object_init()`. Storage for private GEM objects +must be managed by drivers. + +GEM Objects Lifetime +~~~~~~~~~~~~~~~~~~~~ + +All GEM objects are reference-counted by the GEM core. References can be +acquired and release by :c:func:`calling +drm_gem_object_reference()` and +:c:func:`drm_gem_object_unreference()` respectively. The caller +must hold the :c:type:`struct drm_device ` +struct_mutex lock when calling +:c:func:`drm_gem_object_reference()`. As a convenience, GEM +provides :c:func:`drm_gem_object_unreference_unlocked()` +functions that can be called without holding the lock. + +When the last reference to a GEM object is released the GEM core calls +the :c:type:`struct drm_driver ` gem_free_object +operation. That operation is mandatory for GEM-enabled drivers and must +free the GEM object and all associated resources. + +void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are +responsible for freeing all GEM object resources. This includes the +resources created by the GEM core, which need to be released with +:c:func:`drm_gem_object_release()`. + +GEM Objects Naming +~~~~~~~~~~~~~~~~~~ + +Communication between userspace and the kernel refers to GEM objects +using local handles, global names or, more recently, file descriptors. +All of those are 32-bit integer values; the usual Linux kernel limits +apply to the file descriptors. + +GEM handles are local to a DRM file. Applications get a handle to a GEM +object through a driver-specific ioctl, and can use that handle to refer +to the GEM object in other standard or driver-specific ioctls. Closing a +DRM file handle frees all its GEM handles and dereferences the +associated GEM objects. + +To create a handle for a GEM object drivers call +:c:func:`drm_gem_handle_create()`. The function takes a pointer +to the DRM file and the GEM object and returns a locally unique handle. +When the handle is no longer needed drivers delete it with a call to +:c:func:`drm_gem_handle_delete()`. Finally the GEM object +associated with a handle can be retrieved by a call to +:c:func:`drm_gem_object_lookup()`. + +Handles don't take ownership of GEM objects, they only take a reference +to the object that will be dropped when the handle is destroyed. To +avoid leaking GEM objects, drivers must make sure they drop the +reference(s) they own (such as the initial reference taken at object +creation time) as appropriate, without any special consideration for the +handle. For example, in the particular case of combined GEM object and +handle creation in the implementation of the dumb_create operation, +drivers must drop the initial reference to the GEM object before +returning the handle. + +GEM names are similar in purpose to handles but are not local to DRM +files. They can be passed between processes to reference a GEM object +globally. Names can't be used directly to refer to objects in the DRM +API, applications must convert handles to names and names to handles +using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls +respectively. The conversion is handled by the DRM core without any +driver-specific support. + +GEM also supports buffer sharing with dma-buf file descriptors through +PRIME. GEM-based drivers must use the provided helpers functions to +implement the exporting and importing correctly. See ?. Since sharing +file descriptors is inherently more secure than the easily guessable and +global GEM names it is the preferred buffer sharing mechanism. Sharing +buffers through GEM names is only supported for legacy userspace. +Furthermore PRIME also allows cross-device buffer sharing since it is +based on dma-bufs. + +GEM Objects Mapping +~~~~~~~~~~~~~~~~~~~ + +Because mapping operations are fairly heavyweight GEM favours +read/write-like access to buffers, implemented through driver-specific +ioctls, over mapping buffers to userspace. However, when random access +to the buffer is needed (to perform software rendering for instance), +direct access to the object can be more efficient. + +The mmap system call can't be used directly to map GEM objects, as they +don't have their own file handle. Two alternative methods currently +co-exist to map GEM objects to userspace. The first method uses a +driver-specific ioctl to perform the mapping operation, calling +:c:func:`do_mmap()` under the hood. This is often considered +dubious, seems to be discouraged for new GEM-enabled drivers, and will +thus not be described here. + +The second method uses the mmap system call on the DRM file handle. void +\*mmap(void \*addr, size_t length, int prot, int flags, int fd, off_t +offset); DRM identifies the GEM object to be mapped by a fake offset +passed through the mmap offset argument. Prior to being mapped, a GEM +object must thus be associated with a fake offset. To do so, drivers +must call :c:func:`drm_gem_create_mmap_offset()` on the object. + +Once allocated, the fake offset value must be passed to the application +in a driver-specific way and can then be used as the mmap offset +argument. + +The GEM core provides a helper method :c:func:`drm_gem_mmap()` to +handle object mapping. The method can be set directly as the mmap file +operation handler. It will look up the GEM object based on the offset +value and set the VMA operations to the :c:type:`struct drm_driver +` gem_vm_ops field. Note that +:c:func:`drm_gem_mmap()` doesn't map memory to userspace, but +relies on the driver-provided fault handler to map pages individually. + +To use :c:func:`drm_gem_mmap()`, drivers must fill the struct +:c:type:`struct drm_driver ` gem_vm_ops field +with a pointer to VM operations. + +struct vm_operations_struct \*gem_vm_ops struct +vm_operations_struct { void (\*open)(struct vm_area_struct \* area); +void (\*close)(struct vm_area_struct \* area); int (\*fault)(struct +vm_area_struct \*vma, struct vm_fault \*vmf); }; + +The open and close operations must update the GEM object reference +count. Drivers can use the :c:func:`drm_gem_vm_open()` and +:c:func:`drm_gem_vm_close()` helper functions directly as open +and close handlers. + +The fault operation handler is responsible for mapping individual pages +to userspace when a page fault occurs. Depending on the memory +allocation scheme, drivers can allocate pages at fault time, or can +decide to allocate memory for the GEM object at the time the object is +created. + +Drivers that want to map the GEM object upfront instead of handling page +faults can implement their own mmap file operation handler. + +Memory Coherency +~~~~~~~~~~~~~~~~ + +When mapped to the device or used in a command buffer, backing pages for +an object are flushed to memory and marked write combined so as to be +coherent with the GPU. Likewise, if the CPU accesses an object after the +GPU has finished rendering to the object, then the object must be made +coherent with the CPU's view of memory, usually involving GPU cache +flushing of various kinds. This core CPU<->GPU coherency management is +provided by a device-specific ioctl, which evaluates an object's current +domain and performs any necessary flushing or synchronization to put the +object into the desired coherency domain (note that the object may be +busy, i.e. an active render target; in that case, setting the domain +blocks the client and waits for rendering to complete before performing +any necessary flushing operations). + +Command Execution +~~~~~~~~~~~~~~~~~ + +Perhaps the most important GEM function for GPU devices is providing a +command execution interface to clients. Client programs construct +command buffers containing references to previously allocated memory +objects, and then submit them to GEM. At that point, GEM takes care to +bind all the objects into the GTT, execute the buffer, and provide +necessary synchronization between clients accessing the same buffers. +This often involves evicting some objects from the GTT and re-binding +others (a fairly expensive operation), and providing relocation support +which hides fixed GTT offsets from clients. Clients must take care not +to submit command buffers that reference more objects than can fit in +the GTT; otherwise, GEM will reject them and no rendering will occur. +Similarly, if several objects in the buffer require fence registers to +be allocated for correct rendering (e.g. 2D blits on pre-965 chips), +care must be taken not to require more fence registers than are +available to the client. Such resource management should be abstracted +from the client in libdrm. + +GEM Function Reference +---------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_gem.c + :export: + +.. kernel-doc:: include/drm/drm_gem.h + :internal: + +VMA Offset Manager +------------------ + +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :doc: vma offset manager + +.. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c + :export: + +.. kernel-doc:: include/drm/drm_vma_manager.h + :internal: + +PRIME Buffer Sharing +-------------------- + +PRIME is the cross device buffer sharing framework in drm, originally +created for the OPTIMUS range of multi-gpu platforms. To userspace PRIME +buffers are dma-buf based file descriptors. + +Overview and Driver Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Similar to GEM global names, PRIME file descriptors are also used to +share buffer objects across processes. They offer additional security: +as file descriptors must be explicitly sent over UNIX domain sockets to +be shared between applications, they can't be guessed like the globally +unique GEM names. + +Drivers that support the PRIME API must set the DRIVER_PRIME bit in the +struct :c:type:`struct drm_driver ` +driver_features field, and implement the prime_handle_to_fd and +prime_fd_to_handle operations. + +int (\*prime_handle_to_fd)(struct drm_device \*dev, struct drm_file +\*file_priv, uint32_t handle, uint32_t flags, int \*prime_fd); int +(\*prime_fd_to_handle)(struct drm_device \*dev, struct drm_file +\*file_priv, int prime_fd, uint32_t \*handle); Those two operations +convert a handle to a PRIME file descriptor and vice versa. Drivers must +use the kernel dma-buf buffer sharing framework to manage the PRIME file +descriptors. Similar to the mode setting API PRIME is agnostic to the +underlying buffer object manager, as long as handles are 32bit unsigned +integers. + +While non-GEM drivers must implement the operations themselves, GEM +drivers must use the :c:func:`drm_gem_prime_handle_to_fd()` and +:c:func:`drm_gem_prime_fd_to_handle()` helper functions. Those +helpers rely on the driver gem_prime_export and gem_prime_import +operations to create a dma-buf instance from a GEM object (dma-buf +exporter role) and to create a GEM object from a dma-buf instance +(dma-buf importer role). + +struct dma_buf \* (\*gem_prime_export)(struct drm_device \*dev, +struct drm_gem_object \*obj, int flags); struct drm_gem_object \* +(\*gem_prime_import)(struct drm_device \*dev, struct dma_buf +\*dma_buf); These two operations are mandatory for GEM drivers that +support PRIME. + +PRIME Helper Functions +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_prime.c + :doc: PRIME Helpers + +PRIME Function References +------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_prime.c + :export: + +DRM MM Range Allocator +---------------------- + +Overview +~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :doc: Overview + +LRU Scan/Eviction Support +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :doc: lru scan roaster + +DRM MM Range Allocator Function References +------------------------------------------ + +.. kernel-doc:: drivers/gpu/drm/drm_mm.c + :export: + +.. kernel-doc:: include/drm/drm_mm.h + :internal: + +CMA Helper Functions Reference +------------------------------ + +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :doc: cma helpers + +.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c + :export: + +.. kernel-doc:: include/drm/drm_gem_cma_helper.h + :internal: diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index e6b38e8e57c9..fcac0fa72056 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -6,6 +6,9 @@ Linux GPU Driver Developer's Guide introduction drm-internals + drm-mm + drm-kms + drm-kms-helpers drm-uapi i915 vga-switcheroo -- cgit v1.3-14-g43fede From 88e196b337d662a7c9c342ffeac3a65dc1b0d11f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Jun 2016 14:49:03 +0300 Subject: Documentation/DocBook: remove gpu.tmpl The gpu documentation has now been converted to reStructuredText files under Documentation/gpu. Remove the obsolete DocBook template. Also remove it from MAINTAINERS. Good riddance. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/8d673f75fe686371ed9838682c368a4e3b96bf54.1466506505.git.jani.nikula@intel.com --- Documentation/DocBook/Makefile | 2 +- Documentation/DocBook/gpu.tmpl | 3528 ---------------------------------------- MAINTAINERS | 1 - 3 files changed, 1 insertion(+), 3530 deletions(-) delete mode 100644 Documentation/DocBook/gpu.tmpl (limited to 'Documentation') diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index e0c7e1e0590b..f4482f9b221f 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml device-drivers.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ 80211.xml debugobjects.xml sh.xml regulator.xml \ alsa-driver-api.xml writing-an-alsa-driver.xml \ - tracepoint.xml gpu.xml media_api.xml w1.xml \ + tracepoint.xml media_api.xml w1.xml \ writing_musb_glue_layer.xml crypto-API.xml iio.xml include Documentation/DocBook/media/Makefile diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl deleted file mode 100644 index d09536c91717..000000000000 --- a/Documentation/DocBook/gpu.tmpl +++ /dev/null @@ -1,3528 +0,0 @@ - - - - - - Linux GPU Driver Developer's Guide - - - - Jesse - Barnes - Initial version - - Intel Corporation -

- jesse.barnes@intel.com -
- - - - Laurent - Pinchart - Driver internals - - Ideas on board SPRL -
- laurent.pinchart@ideasonboard.com -
-
-
- - Daniel - Vetter - Contributions all over the place - - Intel Corporation -
- daniel.vetter@ffwll.ch -
-
-
- - Lukas - Wunner - vga_switcheroo documentation - -
- lukas@wunner.de -
-
-
- - - - 2008-2009 - 2013-2014 - Intel Corporation - - - 2012 - Laurent Pinchart - - - 2015 - Lukas Wunner - - - - - The contents of this file may be used under the terms of the GNU - General Public License version 2 (the "GPL") as distributed in - the kernel source COPYING file. - - - - - - - 1.0 - 2012-07-13 - LP - Added extensive documentation about driver internals. - - - - 1.1 - 2015-10-11 - LW - Added vga_switcheroo documentation. - - - - - - - - - DRM Core - - - This first part of the GPU Driver Developer's Guide documents core DRM - code, helper libraries for writing drivers and generic userspace - interfaces exposed by DRM drivers. - - - - - Introduction - - The Linux DRM layer contains code intended to support the needs - of complex graphics devices, usually containing programmable - pipelines well suited to 3D graphics acceleration. Graphics - drivers in the kernel may make use of DRM functions to make - tasks like memory management, interrupt handling and DMA easier, - and provide a uniform interface to applications. - - - A note on versions: this guide covers features found in the DRM - tree, including the TTM memory manager, output configuration and - mode setting, and the new vblank internals, in addition to all - the regular features found in current kernels. - - - [Insert diagram of typical DRM stack here] - - - Style Guidelines - - For consistency this documentation uses American English. Abbreviations - are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so - on. To aid in reading, documentations make full use of the markup - characters kerneldoc provides: @parameter for function parameters, @member - for structure members, &structure to reference structures and - function() for functions. These all get automatically hyperlinked if - kerneldoc for the referenced objects exists. When referencing entries in - function vtables please use ->vfunc(). Note that kerneldoc does - not support referencing struct members directly, so please add a reference - to the vtable struct somewhere in the same paragraph or at least section. - - - Except in special situations (to separate locked from unlocked variants) - locking requirements for functions aren't documented in the kerneldoc. - Instead locking should be check at runtime using e.g. - WARN_ON(!mutex_is_locked(...));. Since it's much easier to - ignore documentation than runtime noise this provides more value. And on - top of that runtime checks do need to be updated when the locking rules - change, increasing the chances that they're correct. Within the - documentation the locking rules should be explained in the relevant - structures: Either in the comment for the lock explaining what it - protects, or data fields need a note about which lock protects them, or - both. - - - Functions which have a non-void return value should have a - section called "Returns" explaining the expected return values in - different cases and their meanings. Currently there's no consensus whether - that section name should be all upper-case or not, and whether it should - end in a colon or not. Go with the file-local style. Other common section - names are "Notes" with information for dangerous or tricky corner cases, - and "FIXME" where the interface could be cleaned up. - - - - - - - - DRM Internals - - This chapter documents DRM internals relevant to driver authors - and developers working to add support for the latest features to - existing drivers. - - - First, we go over some typical driver initialization - requirements, like setting up command buffers, creating an - initial output configuration, and initializing core services. - Subsequent sections cover core internals in more detail, - providing implementation notes and examples. - - - The DRM layer provides several services to graphics drivers, - many of them driven by the application interfaces it provides - through libdrm, the library that wraps most of the DRM ioctls. - These include vblank event handling, memory - management, output management, framebuffer management, command - submission & fencing, suspend/resume support, and DMA - services. - - - - - - Driver Initialization - - At the core of every DRM driver is a drm_driver - structure. Drivers typically statically initialize a drm_driver structure, - and then pass it to drm_dev_alloc() to allocate a - device instance. After the device instance is fully initialized it can be - registered (which makes it accessible from userspace) using - drm_dev_register(). - - - The drm_driver structure contains static - information that describes the driver and features it supports, and - pointers to methods that the DRM core will call to implement the DRM API. - We will first go through the drm_driver static - information fields, and will then describe individual operations in - details as they get used in later sections. - - - Driver Information - - Driver Features - - Drivers inform the DRM core about their requirements and supported - features by setting appropriate flags in the - driver_features field. Since those flags - influence the DRM core behaviour since registration time, most of them - must be set to registering the drm_driver - instance. - - u32 driver_features; - - Driver Feature Flags - - DRIVER_USE_AGP - - Driver uses AGP interface, the DRM core will manage AGP resources. - - - - DRIVER_REQUIRE_AGP - - Driver needs AGP interface to function. AGP initialization failure - will become a fatal error. - - - - DRIVER_PCI_DMA - - Driver is capable of PCI DMA, mapping of PCI DMA buffers to - userspace will be enabled. Deprecated. - - - - DRIVER_SG - - Driver can perform scatter/gather DMA, allocation and mapping of - scatter/gather buffers will be enabled. Deprecated. - - - - DRIVER_HAVE_DMA - - Driver supports DMA, the userspace DMA API will be supported. - Deprecated. - - - - DRIVER_HAVE_IRQDRIVER_IRQ_SHARED - - DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler - managed by the DRM Core. The core will support simple IRQ handler - installation when the flag is set. The installation process is - described in . - DRIVER_IRQ_SHARED indicates whether the device & handler - support shared IRQs (note that this is required of PCI drivers). - - - - DRIVER_GEM - - Driver use the GEM memory manager. - - - - DRIVER_MODESET - - Driver supports mode setting interfaces (KMS). - - - - DRIVER_PRIME - - Driver implements DRM PRIME buffer sharing. - - - - DRIVER_RENDER - - Driver supports dedicated render nodes. - - - - DRIVER_ATOMIC - - Driver supports atomic properties. In this case the driver - must implement appropriate obj->atomic_get_property() vfuncs - for any modeset objects with driver specific properties. - - - - - - Major, Minor and Patchlevel - int major; -int minor; -int patchlevel; - - The DRM core identifies driver versions by a major, minor and patch - level triplet. The information is printed to the kernel log at - initialization time and passed to userspace through the - DRM_IOCTL_VERSION ioctl. - - - The major and minor numbers are also used to verify the requested driver - API version passed to DRM_IOCTL_SET_VERSION. When the driver API changes - between minor versions, applications can call DRM_IOCTL_SET_VERSION to - select a specific version of the API. If the requested major isn't equal - to the driver major, or the requested minor is larger than the driver - minor, the DRM_IOCTL_SET_VERSION call will return an error. Otherwise - the driver's set_version() method will be called with the requested - version. - - - - Name, Description and Date - char *name; -char *desc; -char *date; - - The driver name is printed to the kernel log at initialization time, - used for IRQ registration and passed to userspace through - DRM_IOCTL_VERSION. - - - The driver description is a purely informative string passed to - userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by - the kernel. - - - The driver date, formatted as YYYYMMDD, is meant to identify the date of - the latest modification to the driver. However, as most drivers fail to - update it, its value is mostly useless. The DRM core prints it to the - kernel log at initialization time and passes it to userspace through the - DRM_IOCTL_VERSION ioctl. - - - - - Device Instance and Driver Handling -!Pdrivers/gpu/drm/drm_drv.c driver instance overview -!Edrivers/gpu/drm/drm_drv.c - - - Driver Load - - IRQ Registration - - The DRM core tries to facilitate IRQ handler registration and - unregistration by providing drm_irq_install and - drm_irq_uninstall functions. Those functions only - support a single interrupt per device, devices that use more than one - IRQs need to be handled manually. - - - Managed IRQ Registration - - drm_irq_install starts by calling the - irq_preinstall driver operation. The operation - is optional and must make sure that the interrupt will not get fired by - clearing all pending interrupt flags or disabling the interrupt. - - - The passed-in IRQ will then be requested by a call to - request_irq. If the DRIVER_IRQ_SHARED driver - feature flag is set, a shared (IRQF_SHARED) IRQ handler will be - requested. - - - The IRQ handler function must be provided as the mandatory irq_handler - driver operation. It will get passed directly to - request_irq and thus has the same prototype as all - IRQ handlers. It will get called with a pointer to the DRM device as the - second argument. - - - Finally the function calls the optional - irq_postinstall driver operation. The operation - usually enables interrupts (excluding the vblank interrupt, which is - enabled separately), but drivers may choose to enable/disable interrupts - at a different time. - - - drm_irq_uninstall is similarly used to uninstall an - IRQ handler. It starts by waking up all processes waiting on a vblank - interrupt to make sure they don't hang, and then calls the optional - irq_uninstall driver operation. The operation - must disable all hardware interrupts. Finally the function frees the IRQ - by calling free_irq. - - - - Manual IRQ Registration - - Drivers that require multiple interrupt handlers can't use the managed - IRQ registration functions. In that case IRQs must be registered and - unregistered manually (usually with the request_irq - and free_irq functions, or their devm_* equivalent). - - - When manually registering IRQs, drivers must not set the DRIVER_HAVE_IRQ - driver feature flag, and must not provide the - irq_handler driver operation. They must set the - drm_device irq_enabled - field to 1 upon registration of the IRQs, and clear it to 0 after - unregistering the IRQs. - - - - - Memory Manager Initialization - - Every DRM driver requires a memory manager which must be initialized at - load time. DRM currently contains two memory managers, the Translation - Table Manager (TTM) and the Graphics Execution Manager (GEM). - This document describes the use of the GEM memory manager only. See - for details. - - - - Miscellaneous Device Configuration - - Another task that may be necessary for PCI devices during configuration - is mapping the video BIOS. On many devices, the VBIOS describes device - configuration, LCD panel timings (if any), and contains flags indicating - device state. Mapping the BIOS can be done using the pci_map_rom() call, - a convenience function that takes care of mapping the actual ROM, - whether it has been shadowed into memory (typically at address 0xc0000) - or exists on the PCI device in the ROM BAR. Note that after the ROM has - been mapped and any necessary information has been extracted, it should - be unmapped; on many devices, the ROM address decoder is shared with - other BARs, so leaving it mapped could cause undesired behaviour like - hangs or memory corruption. - - - - - - Bus-specific Device Registration and PCI Support - - A number of functions are provided to help with device registration. - The functions deal with PCI and platform devices respectively and are - only provided for historical reasons. These are all deprecated and - shouldn't be used in new drivers. Besides that there's a few - helpers for pci drivers. - -!Edrivers/gpu/drm/drm_pci.c -!Edrivers/gpu/drm/drm_platform.c - - - - - - - Memory management - - Modern Linux systems require large amount of graphics memory to store - frame buffers, textures, vertices and other graphics-related data. Given - the very dynamic nature of many of that data, managing graphics memory - efficiently is thus crucial for the graphics stack and plays a central - role in the DRM infrastructure. - - - The DRM core includes two memory managers, namely Translation Table Maps - (TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory - manager to be developed and tried to be a one-size-fits-them all - solution. It provides a single userspace API to accommodate the need of - all hardware, supporting both Unified Memory Architecture (UMA) devices - and devices with dedicated video RAM (i.e. most discrete video cards). - This resulted in a large, complex piece of code that turned out to be - hard to use for driver development. - - - GEM started as an Intel-sponsored project in reaction to TTM's - complexity. Its design philosophy is completely different: instead of - providing a solution to every graphics memory-related problems, GEM - identified common code between drivers and created a support library to - share it. GEM has simpler initialization and execution requirements than - TTM, but has no video RAM management capabilities and is thus limited to - UMA devices. - - - The Translation Table Manager (TTM) - - TTM design background and information belongs here. - - - TTM initialization - This section is outdated. - - Drivers wishing to support TTM must fill out a drm_bo_driver - structure. The structure contains several fields with function - pointers for initializing the TTM, allocating and freeing memory, - waiting for command completion and fence synchronization, and memory - migration. See the radeon_ttm.c file for an example of usage. - - - The ttm_global_reference structure is made up of several fields: - - - struct ttm_global_reference { - enum ttm_global_types global_type; - size_t size; - void *object; - int (*init) (struct ttm_global_reference *); - void (*release) (struct ttm_global_reference *); - }; - - - There should be one global reference structure for your memory - manager as a whole, and there will be others for each object - created by the memory manager at runtime. Your global TTM should - have a type of TTM_GLOBAL_TTM_MEM. The size field for the global - object should be sizeof(struct ttm_mem_global), and the init and - release hooks should point at your driver-specific init and - release routines, which probably eventually call - ttm_mem_global_init and ttm_mem_global_release, respectively. - - - Once your global TTM accounting structure is set up and initialized - by calling ttm_global_item_ref() on it, - you need to create a buffer object TTM to - provide a pool for buffer object allocation by clients and the - kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, - and its size should be sizeof(struct ttm_bo_global). Again, - driver-specific init and release functions may be provided, - likely eventually calling ttm_bo_global_init() and - ttm_bo_global_release(), respectively. Also, like the previous - object, ttm_global_item_ref() is used to create an initial reference - count for the TTM, which will call your initialization function. - - - - - The Graphics Execution Manager (GEM) - - The GEM design approach has resulted in a memory manager that doesn't - provide full coverage of all (or even all common) use cases in its - userspace or kernel API. GEM exposes a set of standard memory-related - operations to userspace and a set of helper functions to drivers, and let - drivers implement hardware-specific operations with their own private API. - - - The GEM userspace API is described in the - GEM - the Graphics - Execution Manager article on LWN. While slightly - outdated, the document provides a good overview of the GEM API principles. - Buffer allocation and read and write operations, described as part of the - common GEM API, are currently implemented using driver-specific ioctls. - - - GEM is data-agnostic. It manages abstract buffer objects without knowing - what individual buffers contain. APIs that require knowledge of buffer - contents or purpose, such as buffer allocation or synchronization - primitives, are thus outside of the scope of GEM and must be implemented - using driver-specific ioctls. - - - On a fundamental level, GEM involves several operations: - - Memory allocation and freeing - Command execution - Aperture management at command execution time - - Buffer object allocation is relatively straightforward and largely - provided by Linux's shmem layer, which provides memory to back each - object. - - - Device-specific operations, such as command execution, pinning, buffer - read & write, mapping, and domain ownership transfers are left to - driver-specific ioctls. - - - GEM Initialization - - Drivers that use GEM must set the DRIVER_GEM bit in the struct - drm_driver - driver_features field. The DRM core will - then automatically initialize the GEM core before calling the - load operation. Behind the scene, this will - create a DRM Memory Manager object which provides an address space - pool for object allocation. - - - In a KMS configuration, drivers need to allocate and initialize a - command ring buffer following core GEM initialization if required by - the hardware. UMA devices usually have what is called a "stolen" - memory region, which provides space for the initial framebuffer and - large, contiguous memory regions required by the device. This space is - typically not managed by GEM, and must be initialized separately into - its own DRM MM object. - - - - GEM Objects Creation - - GEM splits creation of GEM objects and allocation of the memory that - backs them in two distinct operations. - - - GEM objects are represented by an instance of struct - drm_gem_object. Drivers usually need to extend - GEM objects with private information and thus create a driver-specific - GEM object structure type that embeds an instance of struct - drm_gem_object. - - - To create a GEM object, a driver allocates memory for an instance of its - specific GEM object type and initializes the embedded struct - drm_gem_object with a call to - drm_gem_object_init. The function takes a pointer to - the DRM device, a pointer to the GEM object and the buffer object size - in bytes. - - - GEM uses shmem to allocate anonymous pageable memory. - drm_gem_object_init will create an shmfs file of - the requested size and store it into the struct - drm_gem_object filp - field. The memory is used as either main storage for the object when the - graphics hardware uses system memory directly or as a backing store - otherwise. - - - Drivers are responsible for the actual physical pages allocation by - calling shmem_read_mapping_page_gfp for each page. - Note that they can decide to allocate pages when initializing the GEM - object, or to delay allocation until the memory is needed (for instance - when a page fault occurs as a result of a userspace memory access or - when the driver needs to start a DMA transfer involving the memory). - - - Anonymous pageable memory allocation is not always desired, for instance - when the hardware requires physically contiguous system memory as is - often the case in embedded devices. Drivers can create GEM objects with - no shmfs backing (called private GEM objects) by initializing them with - a call to drm_gem_private_object_init instead of - drm_gem_object_init. Storage for private GEM - objects must be managed by drivers. - - - - GEM Objects Lifetime - - All GEM objects are reference-counted by the GEM core. References can be - acquired and release by calling drm_gem_object_reference - and drm_gem_object_unreference respectively. The - caller must hold the drm_device - struct_mutex lock when calling - drm_gem_object_reference. As a convenience, GEM - provides drm_gem_object_unreference_unlocked - functions that can be called without holding the lock. - - - When the last reference to a GEM object is released the GEM core calls - the drm_driver - gem_free_object operation. That operation is - mandatory for GEM-enabled drivers and must free the GEM object and all - associated resources. - - - void (*gem_free_object) (struct drm_gem_object *obj); - Drivers are responsible for freeing all GEM object resources. This includes - the resources created by the GEM core, which need to be released with - drm_gem_object_release. - - - - GEM Objects Naming - - Communication between userspace and the kernel refers to GEM objects - using local handles, global names or, more recently, file descriptors. - All of those are 32-bit integer values; the usual Linux kernel limits - apply to the file descriptors. - - - GEM handles are local to a DRM file. Applications get a handle to a GEM - object through a driver-specific ioctl, and can use that handle to refer - to the GEM object in other standard or driver-specific ioctls. Closing a - DRM file handle frees all its GEM handles and dereferences the - associated GEM objects. - - - To create a handle for a GEM object drivers call - drm_gem_handle_create. The function takes a pointer - to the DRM file and the GEM object and returns a locally unique handle. - When the handle is no longer needed drivers delete it with a call to - drm_gem_handle_delete. Finally the GEM object - associated with a handle can be retrieved by a call to - drm_gem_object_lookup. - - - Handles don't take ownership of GEM objects, they only take a reference - to the object that will be dropped when the handle is destroyed. To - avoid leaking GEM objects, drivers must make sure they drop the - reference(s) they own (such as the initial reference taken at object - creation time) as appropriate, without any special consideration for the - handle. For example, in the particular case of combined GEM object and - handle creation in the implementation of the - dumb_create operation, drivers must drop the - initial reference to the GEM object before returning the handle. - - - GEM names are similar in purpose to handles but are not local to DRM - files. They can be passed between processes to reference a GEM object - globally. Names can't be used directly to refer to objects in the DRM - API, applications must convert handles to names and names to handles - using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls - respectively. The conversion is handled by the DRM core without any - driver-specific support. - - - GEM also supports buffer sharing with dma-buf file descriptors through - PRIME. GEM-based drivers must use the provided helpers functions to - implement the exporting and importing correctly. See . - Since sharing file descriptors is inherently more secure than the - easily guessable and global GEM names it is the preferred buffer - sharing mechanism. Sharing buffers through GEM names is only supported - for legacy userspace. Furthermore PRIME also allows cross-device - buffer sharing since it is based on dma-bufs. - - - - GEM Objects Mapping - - Because mapping operations are fairly heavyweight GEM favours - read/write-like access to buffers, implemented through driver-specific - ioctls, over mapping buffers to userspace. However, when random access - to the buffer is needed (to perform software rendering for instance), - direct access to the object can be more efficient. - - - The mmap system call can't be used directly to map GEM objects, as they - don't have their own file handle. Two alternative methods currently - co-exist to map GEM objects to userspace. The first method uses a - driver-specific ioctl to perform the mapping operation, calling - do_mmap under the hood. This is often considered - dubious, seems to be discouraged for new GEM-enabled drivers, and will - thus not be described here. - - - The second method uses the mmap system call on the DRM file handle. - void *mmap(void *addr, size_t length, int prot, int flags, int fd, - off_t offset); - DRM identifies the GEM object to be mapped by a fake offset passed - through the mmap offset argument. Prior to being mapped, a GEM object - must thus be associated with a fake offset. To do so, drivers must call - drm_gem_create_mmap_offset on the object. - - - Once allocated, the fake offset value - must be passed to the application in a driver-specific way and can then - be used as the mmap offset argument. - - - The GEM core provides a helper method drm_gem_mmap - to handle object mapping. The method can be set directly as the mmap - file operation handler. It will look up the GEM object based on the - offset value and set the VMA operations to the - drm_driver gem_vm_ops - field. Note that drm_gem_mmap doesn't map memory to - userspace, but relies on the driver-provided fault handler to map pages - individually. - - - To use drm_gem_mmap, drivers must fill the struct - drm_driver gem_vm_ops - field with a pointer to VM operations. - - - struct vm_operations_struct *gem_vm_ops - - struct vm_operations_struct { - void (*open)(struct vm_area_struct * area); - void (*close)(struct vm_area_struct * area); - int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf); - }; - - - The open and close - operations must update the GEM object reference count. Drivers can use - the drm_gem_vm_open and - drm_gem_vm_close helper functions directly as open - and close handlers. - - - The fault operation handler is responsible for mapping individual pages - to userspace when a page fault occurs. Depending on the memory - allocation scheme, drivers can allocate pages at fault time, or can - decide to allocate memory for the GEM object at the time the object is - created. - - - Drivers that want to map the GEM object upfront instead of handling page - faults can implement their own mmap file operation handler. - - - - Memory Coherency - - When mapped to the device or used in a command buffer, backing pages - for an object are flushed to memory and marked write combined so as to - be coherent with the GPU. Likewise, if the CPU accesses an object - after the GPU has finished rendering to the object, then the object - must be made coherent with the CPU's view of memory, usually involving - GPU cache flushing of various kinds. This core CPU<->GPU - coherency management is provided by a device-specific ioctl, which - evaluates an object's current domain and performs any necessary - flushing or synchronization to put the object into the desired - coherency domain (note that the object may be busy, i.e. an active - render target; in that case, setting the domain blocks the client and - waits for rendering to complete before performing any necessary - flushing operations). - - - - Command Execution - - Perhaps the most important GEM function for GPU devices is providing a - command execution interface to clients. Client programs construct - command buffers containing references to previously allocated memory - objects, and then submit them to GEM. At that point, GEM takes care to - bind all the objects into the GTT, execute the buffer, and provide - necessary synchronization between clients accessing the same buffers. - This often involves evicting some objects from the GTT and re-binding - others (a fairly expensive operation), and providing relocation - support which hides fixed GTT offsets from clients. Clients must take - care not to submit command buffers that reference more objects than - can fit in the GTT; otherwise, GEM will reject them and no rendering - will occur. Similarly, if several objects in the buffer require fence - registers to be allocated for correct rendering (e.g. 2D blits on - pre-965 chips), care must be taken not to require more fence registers - than are available to the client. Such resource management should be - abstracted from the client in libdrm. - - - - - GEM Function Reference -!Edrivers/gpu/drm/drm_gem.c -!Iinclude/drm/drm_gem.h - - - VMA Offset Manager -!Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager -!Edrivers/gpu/drm/drm_vma_manager.c -!Iinclude/drm/drm_vma_manager.h - - - PRIME Buffer Sharing - - PRIME is the cross device buffer sharing framework in drm, originally - created for the OPTIMUS range of multi-gpu platforms. To userspace - PRIME buffers are dma-buf based file descriptors. - - - Overview and Driver Interface - - Similar to GEM global names, PRIME file descriptors are - also used to share buffer objects across processes. They offer - additional security: as file descriptors must be explicitly sent over - UNIX domain sockets to be shared between applications, they can't be - guessed like the globally unique GEM names. - - - Drivers that support the PRIME - API must set the DRIVER_PRIME bit in the struct - drm_driver - driver_features field, and implement the - prime_handle_to_fd and - prime_fd_to_handle operations. - - - int (*prime_handle_to_fd)(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, - uint32_t flags, int *prime_fd); -int (*prime_fd_to_handle)(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, - uint32_t *handle); - Those two operations convert a handle to a PRIME file descriptor and - vice versa. Drivers must use the kernel dma-buf buffer sharing framework - to manage the PRIME file descriptors. Similar to the mode setting - API PRIME is agnostic to the underlying buffer object manager, as - long as handles are 32bit unsigned integers. - - - While non-GEM drivers must implement the operations themselves, GEM - drivers must use the drm_gem_prime_handle_to_fd - and drm_gem_prime_fd_to_handle helper functions. - Those helpers rely on the driver - gem_prime_export and - gem_prime_import operations to create a dma-buf - instance from a GEM object (dma-buf exporter role) and to create a GEM - object from a dma-buf instance (dma-buf importer role). - - - struct dma_buf * (*gem_prime_export)(struct drm_device *dev, - struct drm_gem_object *obj, - int flags); -struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, - struct dma_buf *dma_buf); - These two operations are mandatory for GEM drivers that support - PRIME. - - - - PRIME Helper Functions -!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers - - - - PRIME Function References -!Edrivers/gpu/drm/drm_prime.c - - - DRM MM Range Allocator - - Overview -!Pdrivers/gpu/drm/drm_mm.c Overview - - - LRU Scan/Eviction Support -!Pdrivers/gpu/drm/drm_mm.c lru scan roaster - - - - DRM MM Range Allocator Function References -!Edrivers/gpu/drm/drm_mm.c -!Iinclude/drm/drm_mm.h - - - CMA Helper Functions Reference -!Pdrivers/gpu/drm/drm_gem_cma_helper.c cma helpers -!Edrivers/gpu/drm/drm_gem_cma_helper.c -!Iinclude/drm/drm_gem_cma_helper.h - - - - - - - Mode Setting - - Drivers must initialize the mode setting core by calling - drm_mode_config_init on the DRM device. The function - initializes the drm_device - mode_config field and never fails. Once done, - mode configuration must be setup by initializing the following fields. - - - - int min_width, min_height; -int max_width, max_height; - - Minimum and maximum width and height of the frame buffers in pixel - units. - - - - struct drm_mode_config_funcs *funcs; - Mode setting functions. - - - - Display Modes Function Reference -!Iinclude/drm/drm_modes.h -!Edrivers/gpu/drm/drm_modes.c - - - Atomic Mode Setting Function Reference -!Edrivers/gpu/drm/drm_atomic.c -!Idrivers/gpu/drm/drm_atomic.c - - - Frame Buffer Abstraction - - Frame buffers are abstract memory objects that provide a source of - pixels to scanout to a CRTC. Applications explicitly request the - creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and - receive an opaque handle that can be passed to the KMS CRTC control, - plane configuration and page flip functions. - - - Frame buffers rely on the underneath memory manager for low-level memory - operations. When creating a frame buffer applications pass a memory - handle (or a list of memory handles for multi-planar formats) through - the drm_mode_fb_cmd2 argument. For drivers using - GEM as their userspace buffer management interface this would be a GEM - handle. Drivers are however free to use their own backing storage object - handles, e.g. vmwgfx directly exposes special TTM handles to userspace - and so expects TTM handles in the create ioctl and not GEM handles. - - - The lifetime of a drm framebuffer is controlled with a reference count, - drivers can grab additional references with - drm_framebuffer_referenceand drop them - again with drm_framebuffer_unreference. For - driver-private framebuffers for which the last reference is never - dropped (e.g. for the fbdev framebuffer when the struct - drm_framebuffer is embedded into the fbdev - helper struct) drivers can manually clean up a framebuffer at module - unload time with - drm_framebuffer_unregister_private. - - - - DRM Format Handling -!Iinclude/drm/drm_fourcc.h -!Edrivers/gpu/drm/drm_fourcc.c - - - Dumb Buffer Objects - - The KMS API doesn't standardize backing storage object creation and - leaves it to driver-specific ioctls. Furthermore actually creating a - buffer object even for GEM-based drivers is done through a - driver-specific ioctl - GEM only has a common userspace interface for - sharing and destroying objects. While not an issue for full-fledged - graphics stacks that include device-specific userspace components (in - libdrm for instance), this limit makes DRM-based early boot graphics - unnecessarily complex. - - - Dumb objects partly alleviate the problem by providing a standard - API to create dumb buffers suitable for scanout, which can then be used - to create KMS frame buffers. - - - To support dumb objects drivers must implement the - dumb_create, - dumb_destroy and - dumb_map_offset operations. - - - - int (*dumb_create)(struct drm_file *file_priv, struct drm_device *dev, - struct drm_mode_create_dumb *args); - - The dumb_create operation creates a driver - object (GEM or TTM handle) suitable for scanout based on the - width, height and depth from the struct - drm_mode_create_dumb argument. It fills the - argument's handle, - pitch and size - fields with a handle for the newly created object and its line - pitch and size in bytes. - - - - int (*dumb_destroy)(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle); - - The dumb_destroy operation destroys a dumb - object created by dumb_create. - - - - int (*dumb_map_offset)(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle, uint64_t *offset); - - The dumb_map_offset operation associates an - mmap fake offset with the object given by the handle and returns - it. Drivers must use the - drm_gem_create_mmap_offset function to - associate the fake offset as described in - . - - - - - Note that dumb objects may not be used for gpu acceleration, as has been - attempted on some ARM embedded platforms. Such drivers really must have - a hardware-specific ioctl to allocate suitable buffer objects. - - - - Output Polling - void (*output_poll_changed)(struct drm_device *dev); - - This operation notifies the driver that the status of one or more - connectors has changed. Drivers that use the fb helper can just call the - drm_fb_helper_hotplug_event function to handle this - operation. - - - - - - - - KMS Initialization and Cleanup - - A KMS device is abstracted and exposed as a set of planes, CRTCs, encoders - and connectors. KMS drivers must thus create and initialize all those - objects at load time after initializing mode setting. - - - CRTCs (struct <structname>drm_crtc</structname>) - - A CRTC is an abstraction representing a part of the chip that contains a - pointer to a scanout buffer. Therefore, the number of CRTCs available - determines how many independent scanout buffers can be active at any - given time. The CRTC structure contains several fields to support this: - a pointer to some video memory (abstracted as a frame buffer object), a - display mode, and an (x, y) offset into the video memory to support - panning or configurations where one piece of video memory spans multiple - CRTCs. - - - CRTC Initialization - - A KMS device must create and register at least one struct - drm_crtc instance. The instance is allocated - and zeroed by the driver, possibly as part of a larger structure, and - registered with a call to drm_crtc_init with a - pointer to CRTC functions. - - - - - Planes (struct <structname>drm_plane</structname>) - - A plane represents an image source that can be blended with or overlayed - on top of a CRTC during the scanout process. Planes are associated with - a frame buffer to crop a portion of the image memory (source) and - optionally scale it to a destination size. The result is then blended - with or overlayed on top of a CRTC. - - - The DRM core recognizes three types of planes: - - - DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. Primary - planes are the planes operated upon by CRTC modesetting and flipping - operations described in the page_flip hook in drm_crtc_funcs. - - - DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. Cursor - planes are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and - DRM_IOCTL_MODE_CURSOR2 ioctls. - - - DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor planes. - Some drivers refer to these types of planes as "sprites" internally. - - - For compatibility with legacy userspace, only overlay planes are made - available to userspace by default. Userspace clients may set the - DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that - they wish to receive a universal plane list containing all plane types. - - - Plane Initialization - - To create a plane, a KMS drivers allocates and - zeroes an instances of struct drm_plane - (possibly as part of a larger structure) and registers it with a call - to drm_universal_plane_init. The function takes a bitmask - of the CRTCs that can be associated with the plane, a pointer to the - plane functions, a list of format supported formats, and the type of - plane (primary, cursor, or overlay) being initialized. - - - Cursor and overlay planes are optional. All drivers should provide - one primary plane per CRTC (although this requirement may change in - the future); drivers that do not wish to provide special handling for - primary planes may make use of the helper functions described in - to create and register a - primary plane with standard capabilities. - - - - - Encoders (struct <structname>drm_encoder</structname>) - - An encoder takes pixel data from a CRTC and converts it to a format - suitable for any attached connectors. On some devices, it may be - possible to have a CRTC send data to more than one encoder. In that - case, both encoders would receive data from the same scanout buffer, - resulting in a "cloned" display configuration across the connectors - attached to each encoder. - - - Encoder Initialization - - As for CRTCs, a KMS driver must create, initialize and register at - least one struct drm_encoder instance. The - instance is allocated and zeroed by the driver, possibly as part of a - larger structure. - - - Drivers must initialize the struct drm_encoder - possible_crtcs and - possible_clones fields before registering the - encoder. Both fields are bitmasks of respectively the CRTCs that the - encoder can be connected to, and sibling encoders candidate for cloning. - - - After being initialized, the encoder must be registered with a call to - drm_encoder_init. The function takes a pointer to - the encoder functions and an encoder type. Supported types are - - - DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A - - - DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort - - - DRM_MODE_ENCODER_LVDS for display panels - - - DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, Component, - SCART) - - - DRM_MODE_ENCODER_VIRTUAL for virtual machine displays - - - - - Encoders must be attached to a CRTC to be used. DRM drivers leave - encoders unattached at initialization time. Applications (or the fbdev - compatibility layer when implemented) are responsible for attaching the - encoders they want to use to a CRTC. - - - - - Connectors (struct <structname>drm_connector</structname>) - - A connector is the final destination for pixel data on a device, and - usually connects directly to an external display device like a monitor - or laptop panel. A connector can only be attached to one encoder at a - time. The connector is also the structure where information about the - attached display is kept, so it contains fields for display data, EDID - data, DPMS & connection status, and information about modes - supported on the attached displays. - - - Connector Initialization - - Finally a KMS driver must create, initialize, register and attach at - least one struct drm_connector instance. The - instance is created as other KMS objects and initialized by setting the - following fields. - - - - interlace_allowed - - Whether the connector can handle interlaced modes. - - - - doublescan_allowed - - Whether the connector can handle doublescan. - - - - display_info - - - Display information is filled from EDID information when a display - is detected. For non hot-pluggable displays such as flat panels in - embedded systems, the driver should initialize the - display_info.width_mm - and - display_info.height_mm - fields with the physical size of the display. - - - - polled - - Connector polling mode, a combination of - - - DRM_CONNECTOR_POLL_HPD - - The connector generates hotplug events and doesn't need to be - periodically polled. The CONNECT and DISCONNECT flags must not - be set together with the HPD flag. - - - - DRM_CONNECTOR_POLL_CONNECT - - Periodically poll the connector for connection. - - - - DRM_CONNECTOR_POLL_DISCONNECT - - Periodically poll the connector for disconnection. - - - - Set to 0 for connectors that don't support connection status - discovery. - - - - - The connector is then registered with a call to - drm_connector_init with a pointer to the connector - functions and a connector type, and exposed through sysfs with a call to - drm_connector_register. - - - Supported connector types are - - DRM_MODE_CONNECTOR_VGA - DRM_MODE_CONNECTOR_DVII - DRM_MODE_CONNECTOR_DVID - DRM_MODE_CONNECTOR_DVIA - DRM_MODE_CONNECTOR_Composite - DRM_MODE_CONNECTOR_SVIDEO - DRM_MODE_CONNECTOR_LVDS - DRM_MODE_CONNECTOR_Component - DRM_MODE_CONNECTOR_9PinDIN - DRM_MODE_CONNECTOR_DisplayPort - DRM_MODE_CONNECTOR_HDMIA - DRM_MODE_CONNECTOR_HDMIB - DRM_MODE_CONNECTOR_TV - DRM_MODE_CONNECTOR_eDP - DRM_MODE_CONNECTOR_VIRTUAL - - - - Connectors must be attached to an encoder to be used. For devices that - map connectors to encoders 1:1, the connector should be attached at - initialization time with a call to - drm_mode_connector_attach_encoder. The driver must - also set the drm_connector - encoder field to point to the attached - encoder. - - - Finally, drivers must initialize the connectors state change detection - with a call to drm_kms_helper_poll_init. If at - least one connector is pollable but can't generate hotplug interrupts - (indicated by the DRM_CONNECTOR_POLL_CONNECT and - DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will - automatically be queued to periodically poll for changes. Connectors - that can generate hotplug interrupts must be marked with the - DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must - call drm_helper_hpd_irq_event. The function will - queue a delayed work to check the state of all connectors, but no - periodic polling will be done. - - - - Connector Operations - - Unless otherwise state, all operations are mandatory. - - - DPMS - void (*dpms)(struct drm_connector *connector, int mode); - - The DPMS operation sets the power state of a connector. The mode - argument is one of - - DRM_MODE_DPMS_ON - DRM_MODE_DPMS_STANDBY - DRM_MODE_DPMS_SUSPEND - DRM_MODE_DPMS_OFF - - - - In all but DPMS_ON mode the encoder to which the connector is attached - should put the display in low-power mode by driving its signals - appropriately. If more than one connector is attached to the encoder - care should be taken not to change the power state of other displays as - a side effect. Low-power mode should be propagated to the encoders and - CRTCs when all related connectors are put in low-power mode. - - - - Modes - int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, - uint32_t max_height); - - Fill the mode list with all supported modes for the connector. If the - max_width and max_height - arguments are non-zero, the implementation must ignore all modes wider - than max_width or higher than - max_height. - - - The connector must also fill in this operation its - display_info - width_mm and - height_mm fields with the connected display - physical size in millimeters. The fields should be set to 0 if the value - isn't known or is not applicable (for instance for projector devices). - - - - Connection Status - - The connection status is updated through polling or hotplug events when - supported (see ). The status - value is reported to userspace through ioctls and must not be used - inside the driver, as it only gets initialized by a call to - drm_mode_getconnector from userspace. - - enum drm_connector_status (*detect)(struct drm_connector *connector, - bool force); - - Check to see if anything is attached to the connector. The - force parameter is set to false whilst polling or - to true when checking the connector due to user request. - force can be used by the driver to avoid - expensive, destructive operations during automated probing. - - - Return connector_status_connected if something is connected to the - connector, connector_status_disconnected if nothing is connected and - connector_status_unknown if the connection state isn't known. - - - Drivers should only return connector_status_connected if the connection - status has really been probed as connected. Connectors that can't detect - the connection status, or failed connection status probes, should return - connector_status_unknown. - - - - - - Cleanup - - The DRM core manages its objects' lifetime. When an object is not needed - anymore the core calls its destroy function, which must clean up and - free every resource allocated for the object. Every - drm_*_init call must be matched with a - corresponding drm_*_cleanup call to cleanup CRTCs - (drm_crtc_cleanup), planes - (drm_plane_cleanup), encoders - (drm_encoder_cleanup) and connectors - (drm_connector_cleanup). Furthermore, connectors - that have been added to sysfs must be removed by a call to - drm_connector_unregister before calling - drm_connector_cleanup. - - - Connectors state change detection must be cleanup up with a call to - drm_kms_helper_poll_fini. - - - - Output discovery and initialization example - base; - drm_connector_init(dev, &intel_output->base, - &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - - drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, - DRM_MODE_ENCODER_DAC); - - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); - - /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return; - } - - intel_output->type = INTEL_OUTPUT_ANALOG; - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); - drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); - - drm_connector_register(connector); -}]]> - - In the example above (taken from the i915 driver), a CRTC, connector and - encoder combination is created. A device-specific i2c bus is also - created for fetching EDID data and performing monitor detection. Once - the process is complete, the new connector is registered with sysfs to - make its properties available to applications. - - - - KMS API Functions -!Edrivers/gpu/drm/drm_crtc.c - - - KMS Data Structures -!Iinclude/drm/drm_crtc.h - - - KMS Locking -!Pdrivers/gpu/drm/drm_modeset_lock.c kms locking -!Iinclude/drm/drm_modeset_lock.h -!Edrivers/gpu/drm/drm_modeset_lock.c - - - - - - - Mode Setting Helper Functions - - The plane, CRTC, encoder and connector functions provided by the drivers - implement the DRM API. They're called by the DRM core and ioctl handlers - to handle device state changes and configuration request. As implementing - those functions often requires logic not specific to drivers, mid-layer - helper functions are available to avoid duplicating boilerplate code. - - - The DRM core contains one mid-layer implementation. The mid-layer provides - implementations of several plane, CRTC, encoder and connector functions - (called from the top of the mid-layer) that pre-process requests and call - lower-level functions provided by the driver (at the bottom of the - mid-layer). For instance, the - drm_crtc_helper_set_config function can be used to - fill the struct drm_crtc_funcs - set_config field. When called, it will split - the set_config operation in smaller, simpler - operations and call the driver to handle them. - - - To use the mid-layer, drivers call drm_crtc_helper_add, - drm_encoder_helper_add and - drm_connector_helper_add functions to install their - mid-layer bottom operations handlers, and fill the - drm_crtc_funcs, - drm_encoder_funcs and - drm_connector_funcs structures with pointers to - the mid-layer top API functions. Installing the mid-layer bottom operation - handlers is best done right after registering the corresponding KMS object. - - - The mid-layer is not split between CRTC, encoder and connector operations. - To use it, a driver must provide bottom functions for all of the three KMS - entities. - - - Atomic Modeset Helper Functions Reference - - Overview -!Pdrivers/gpu/drm/drm_atomic_helper.c overview - - - Implementing Asynchronous Atomic Commit -!Pdrivers/gpu/drm/drm_atomic_helper.c implementing nonblocking commit - - - Atomic State Reset and Initialization -!Pdrivers/gpu/drm/drm_atomic_helper.c atomic state reset and initialization - -!Iinclude/drm/drm_atomic_helper.h -!Edrivers/gpu/drm/drm_atomic_helper.c - - - Modeset Helper Reference for Common Vtables -!Iinclude/drm/drm_modeset_helper_vtables.h -!Pinclude/drm/drm_modeset_helper_vtables.h overview - - - Legacy CRTC/Modeset Helper Functions Reference -!Edrivers/gpu/drm/drm_crtc_helper.c -!Pdrivers/gpu/drm/drm_crtc_helper.c overview - - - Output Probing Helper Functions Reference -!Pdrivers/gpu/drm/drm_probe_helper.c output probing helper overview -!Edrivers/gpu/drm/drm_probe_helper.c - - - fbdev Helper Functions Reference -!Pdrivers/gpu/drm/drm_fb_helper.c fbdev helpers -!Edrivers/gpu/drm/drm_fb_helper.c -!Iinclude/drm/drm_fb_helper.h - - - Framebuffer CMA Helper Functions Reference -!Pdrivers/gpu/drm/drm_fb_cma_helper.c framebuffer cma helper functions -!Edrivers/gpu/drm/drm_fb_cma_helper.c - - - Display Port Helper Functions Reference -!Pdrivers/gpu/drm/drm_dp_helper.c dp helpers -!Iinclude/drm/drm_dp_helper.h -!Edrivers/gpu/drm/drm_dp_helper.c - - - Display Port Dual Mode Adaptor Helper Functions Reference -!Pdrivers/gpu/drm/drm_dp_dual_mode_helper.c dp dual mode helpers -!Iinclude/drm/drm_dp_dual_mode_helper.h -!Edrivers/gpu/drm/drm_dp_dual_mode_helper.c - - - Display Port MST Helper Functions Reference -!Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper -!Iinclude/drm/drm_dp_mst_helper.h -!Edrivers/gpu/drm/drm_dp_mst_topology.c - - - MIPI DSI Helper Functions Reference -!Pdrivers/gpu/drm/drm_mipi_dsi.c dsi helpers -!Iinclude/drm/drm_mipi_dsi.h -!Edrivers/gpu/drm/drm_mipi_dsi.c - - - EDID Helper Functions Reference -!Edrivers/gpu/drm/drm_edid.c - - - Rectangle Utilities Reference -!Pinclude/drm/drm_rect.h rect utils -!Iinclude/drm/drm_rect.h -!Edrivers/gpu/drm/drm_rect.c - - - Flip-work Helper Reference -!Pinclude/drm/drm_flip_work.h flip utils -!Iinclude/drm/drm_flip_work.h -!Edrivers/gpu/drm/drm_flip_work.c - - - HDMI Infoframes Helper Reference - - Strictly speaking this is not a DRM helper library but generally useable - by any driver interfacing with HDMI outputs like v4l or alsa drivers. - But it nicely fits into the overall topic of mode setting helper - libraries and hence is also included here. - -!Iinclude/linux/hdmi.h -!Edrivers/video/hdmi.c - - - Plane Helper Reference -!Edrivers/gpu/drm/drm_plane_helper.c -!Pdrivers/gpu/drm/drm_plane_helper.c overview - - - Tile group -!Pdrivers/gpu/drm/drm_crtc.c Tile group - - - Bridges - - Overview -!Pdrivers/gpu/drm/drm_bridge.c overview - - - Default bridge callback sequence -!Pdrivers/gpu/drm/drm_bridge.c bridge callbacks - -!Edrivers/gpu/drm/drm_bridge.c - - - Panel Helper Reference -!Iinclude/drm/drm_panel.h -!Edrivers/gpu/drm/drm_panel.c -!Pdrivers/gpu/drm/drm_panel.c drm panel - - - Simple KMS Helper Reference -!Iinclude/drm/drm_simple_kms_helper.h -!Edrivers/gpu/drm/drm_simple_kms_helper.c -!Pdrivers/gpu/drm/drm_simple_kms_helper.c overview - - - - - - - KMS Properties - - Drivers may need to expose additional parameters to applications than - those described in the previous sections. KMS supports attaching - properties to CRTCs, connectors and planes and offers a userspace API to - list, get and set the property values. - - - Properties are identified by a name that uniquely defines the property - purpose, and store an associated value. For all property types except blob - properties the value is a 64-bit unsigned integer. - - - KMS differentiates between properties and property instances. Drivers - first create properties and then create and associate individual instances - of those properties to objects. A property can be instantiated multiple - times and associated with different objects. Values are stored in property - instances, and all other property information are stored in the property - and shared between all instances of the property. - - - Every property is created with a type that influences how the KMS core - handles the property. Supported property types are - - - DRM_MODE_PROP_RANGE - Range properties report their minimum and maximum - admissible values. The KMS core verifies that values set by - application fit in that range. - - - DRM_MODE_PROP_ENUM - Enumerated properties take a numerical value that - ranges from 0 to the number of enumerated values defined by the - property minus one, and associate a free-formed string name to each - value. Applications can retrieve the list of defined value-name pairs - and use the numerical value to get and set property instance values. - - - - DRM_MODE_PROP_BITMASK - Bitmask properties are enumeration properties that - additionally restrict all enumerated values to the 0..63 range. - Bitmask property instance values combine one or more of the - enumerated bits defined by the property. - - - DRM_MODE_PROP_BLOB - Blob properties store a binary blob without any format - restriction. The binary blobs are created as KMS standalone objects, - and blob property instance values store the ID of their associated - blob object. - Blob properties are only used for the connector EDID property - and cannot be created by drivers. - - - - - To create a property drivers call one of the following functions depending - on the property type. All property creation functions take property flags - and name, as well as type-specific arguments. - - - struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, - const char *name, - uint64_t min, uint64_t max); - Create a range property with the given minimum and maximum - values. - - - struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, - const char *name, - const struct drm_prop_enum_list *props, - int num_values); - Create an enumerated property. The props - argument points to an array of num_values - value-name pairs. - - - struct drm_property *drm_property_create_bitmask(struct drm_device *dev, - int flags, const char *name, - const struct drm_prop_enum_list *props, - int num_values); - Create a bitmask property. The props - argument points to an array of num_values - value-name pairs. - - - - - Properties can additionally be created as immutable, in which case they - will be read-only for applications but can be modified by the driver. To - create an immutable property drivers must set the DRM_MODE_PROP_IMMUTABLE - flag at property creation time. - - - When no array of value-name pairs is readily available at property - creation time for enumerated or range properties, drivers can create - the property using the drm_property_create function - and manually add enumeration value-name pairs by calling the - drm_property_add_enum function. Care must be taken to - properly specify the property type through the flags - argument. - - - After creating properties drivers can attach property instances to CRTC, - connector and plane objects by calling the - drm_object_attach_property. The function takes a - pointer to the target object, a pointer to the previously created property - and an initial instance value. - - - Existing KMS Properties - - The following table gives description of drm properties exposed by various - modules/drivers. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Owner Module/DriversGroupProperty NameTypeProperty ValuesObject attachedDescription/Restrictions
DRMGeneric“rotation”BITMASK{ 0, "rotate-0" }, - { 1, "rotate-90" }, - { 2, "rotate-180" }, - { 3, "rotate-270" }, - { 4, "reflect-x" }, - { 5, "reflect-y" }CRTC, Planerotate-(degrees) rotates the image by the specified amount in degrees - in counter clockwise direction. reflect-x and reflect-y reflects the - image along the specified axis prior to rotation
“scaling mode”ENUM{ "None", "Full", "Center", "Full aspect" }ConnectorSupported by: amdgpu, gma500, i915, nouveau and radeon.
Connector“EDID”BLOB | IMMUTABLE0ConnectorContains id of edid blob ptr object.
“DPMS”ENUM{ “On”, “Standby”, “Suspend”, “Off” }ConnectorContains DPMS operation mode value.
“PATH”BLOB | IMMUTABLE0ConnectorContains topology path to a connector.
“TILE”BLOB | IMMUTABLE0ConnectorContains tiling information for a connector.
“CRTC_ID”OBJECTDRM_MODE_OBJECT_CRTCConnectorCRTC that connector is attached to (atomic)
Plane“type”ENUM | IMMUTABLE{ "Overlay", "Primary", "Cursor" }PlanePlane type
“SRC_X”RANGEMin=0, Max=UINT_MAXPlaneScanout source x coordinate in 16.16 fixed point (atomic)
“SRC_Y”RANGEMin=0, Max=UINT_MAXPlaneScanout source y coordinate in 16.16 fixed point (atomic)
“SRC_W”RANGEMin=0, Max=UINT_MAXPlaneScanout source width in 16.16 fixed point (atomic)
“SRC_H”RANGEMin=0, Max=UINT_MAXPlaneScanout source height in 16.16 fixed point (atomic)
“CRTC_X”SIGNED_RANGEMin=INT_MIN, Max=INT_MAXPlaneScanout CRTC (destination) x coordinate (atomic)
“CRTC_Y”SIGNED_RANGEMin=INT_MIN, Max=INT_MAXPlaneScanout CRTC (destination) y coordinate (atomic)
“CRTC_W”RANGEMin=0, Max=UINT_MAXPlaneScanout CRTC (destination) width (atomic)
“CRTC_H”RANGEMin=0, Max=UINT_MAXPlaneScanout CRTC (destination) height (atomic)
“FB_ID”OBJECTDRM_MODE_OBJECT_FBPlaneScanout framebuffer (atomic)
“CRTC_ID”OBJECTDRM_MODE_OBJECT_CRTCPlaneCRTC that plane is attached to (atomic)
DVI-I“subconnector”ENUM{ “Unknown”, “DVI-D”, “DVI-A” }ConnectorTBD
“select subconnector”ENUM{ “Automatic”, “DVI-D”, “DVI-A” }ConnectorTBD
TV“subconnector”ENUM{ "Unknown", "Composite", "SVIDEO", "Component", "SCART" }ConnectorTBD
“select subconnector”ENUM{ "Automatic", "Composite", "SVIDEO", "Component", "SCART" }ConnectorTBD
“mode”ENUM{ "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc.ConnectorTBD
“left margin”RANGEMin=0, Max=100ConnectorTBD
“right margin”RANGEMin=0, Max=100ConnectorTBD
“top margin”RANGEMin=0, Max=100ConnectorTBD
“bottom margin”RANGEMin=0, Max=100ConnectorTBD
“brightness”RANGEMin=0, Max=100ConnectorTBD
“contrast”RANGEMin=0, Max=100ConnectorTBD
“flicker reduction”RANGEMin=0, Max=100ConnectorTBD
“overscan”RANGEMin=0, Max=100ConnectorTBD
“saturation”RANGEMin=0, Max=100ConnectorTBD
“hue”RANGEMin=0, Max=100ConnectorTBD
Virtual GPU“suggested X”RANGEMin=0, Max=0xffffffffConnectorproperty to suggest an X offset for a connector
“suggested Y”RANGEMin=0, Max=0xffffffffConnectorproperty to suggest an Y offset for a connector
Optional"aspect ratio"ENUM{ "None", "4:3", "16:9" }ConnectorTDB
“dirty”ENUM | IMMUTABLE{ "Off", "On", "Annotate" }ConnectorTBD
“DEGAMMA_LUT”BLOB0CRTCDRM property to set the degamma lookup table - (LUT) mapping pixel data from the framebuffer before it is - given to the transformation matrix. The data is an interpreted - as an array of struct drm_color_lut elements. Hardware might - choose not to use the full precision of the LUT elements nor - use all the elements of the LUT (for example the hardware - might choose to interpolate between LUT[0] and LUT[4]).
“DEGAMMA_LUT_SIZE”RANGE | IMMUTABLEMin=0, Max=UINT_MAXCRTCDRM property to gives the size of the lookup - table to be set on the DEGAMMA_LUT property (the size depends - on the underlying hardware).
“CTM”BLOB0CRTCDRM property to set the current - transformation matrix (CTM) apply to pixel data after the - lookup through the degamma LUT and before the lookup through - the gamma LUT. The data is an interpreted as a struct - drm_color_ctm.
“GAMMA_LUT”BLOB0CRTCDRM property to set the gamma lookup table - (LUT) mapping pixel data after to the transformation matrix to - data sent to the connector. The data is an interpreted as an - array of struct drm_color_lut elements. Hardware might choose - not to use the full precision of the LUT elements nor use all - the elements of the LUT (for example the hardware might choose - to interpolate between LUT[0] and LUT[4]).
“GAMMA_LUT_SIZE”RANGE | IMMUTABLEMin=0, Max=UINT_MAXCRTCDRM property to gives the size of the lookup - table to be set on the GAMMA_LUT property (the size depends on - the underlying hardware).
i915Generic"Broadcast RGB"ENUM{ "Automatic", "Full", "Limited 16:235" }ConnectorWhen this property is set to Limited 16:235 - and CTM is set, the hardware will be programmed with the - result of the multiplication of CTM by the limited range - matrix to ensure the pixels normaly in the range 0..1.0 are - remapped to the range 16/255..235/255.
“audio”ENUM{ "force-dvi", "off", "auto", "on" }ConnectorTBD
SDVO-TV“mode”ENUM{ "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc.ConnectorTBD
"left_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
"right_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
"top_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
"bottom_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
“hpos”RANGEMin=0, Max= SDVO dependentConnectorTBD
“vpos”RANGEMin=0, Max= SDVO dependentConnectorTBD
“contrast”RANGEMin=0, Max= SDVO dependentConnectorTBD
“saturation”RANGEMin=0, Max= SDVO dependentConnectorTBD
“hue”RANGEMin=0, Max= SDVO dependentConnectorTBD
“sharpness”RANGEMin=0, Max= SDVO dependentConnectorTBD
“flicker_filter”RANGEMin=0, Max= SDVO dependentConnectorTBD
“flicker_filter_adaptive”RANGEMin=0, Max= SDVO dependentConnectorTBD
“flicker_filter_2d”RANGEMin=0, Max= SDVO dependentConnectorTBD
“tv_chroma_filter”RANGEMin=0, Max= SDVO dependentConnectorTBD
“tv_luma_filter”RANGEMin=0, Max= SDVO dependentConnectorTBD
“dot_crawl”RANGEMin=0, Max=1ConnectorTBD
SDVO-TV/LVDS“brightness”RANGEMin=0, Max= SDVO dependentConnectorTBD
CDV gma-500Generic"Broadcast RGB"ENUM{ “Full”, “Limited 16:235” }ConnectorTBD
"Broadcast RGB"ENUM{ “off”, “auto”, “on” }ConnectorTBD
PoulsboGeneric“backlight”RANGEMin=0, Max=100ConnectorTBD
SDVO-TV“mode”ENUM{ "NTSC_M", "NTSC_J", "NTSC_443", "PAL_B" } etc.ConnectorTBD
"left_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
"right_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
"top_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
"bottom_margin"RANGEMin=0, Max= SDVO dependentConnectorTBD
“hpos”RANGEMin=0, Max= SDVO dependentConnectorTBD
“vpos”RANGEMin=0, Max= SDVO dependentConnectorTBD
“contrast”RANGEMin=0, Max= SDVO dependentConnectorTBD
“saturation”RANGEMin=0, Max= SDVO dependentConnectorTBD
“hue”RANGEMin=0, Max= SDVO dependentConnectorTBD
“sharpness”RANGEMin=0, Max= SDVO dependentConnectorTBD
“flicker_filter”RANGEMin=0, Max= SDVO dependentConnectorTBD
“flicker_filter_adaptive”RANGEMin=0, Max= SDVO dependentConnectorTBD
“flicker_filter_2d”RANGEMin=0, Max= SDVO dependentConnectorTBD
“tv_chroma_filter”RANGEMin=0, Max= SDVO dependentConnectorTBD
“tv_luma_filter”RANGEMin=0, Max= SDVO dependentConnectorTBD
“dot_crawl”RANGEMin=0, Max=1ConnectorTBD
SDVO-TV/LVDS“brightness”RANGEMin=0, Max= SDVO dependentConnectorTBD
armadaCRTC"CSC_YUV"ENUM{ "Auto" , "CCIR601", "CCIR709" }CRTCTBD
"CSC_RGB"ENUM{ "Auto", "Computer system", "Studio" }CRTCTBD
Overlay"colorkey"RANGEMin=0, Max=0xffffffPlaneTBD
"colorkey_min"RANGEMin=0, Max=0xffffffPlaneTBD
"colorkey_max"RANGEMin=0, Max=0xffffffPlaneTBD
"colorkey_val"RANGEMin=0, Max=0xffffffPlaneTBD
"colorkey_alpha"RANGEMin=0, Max=0xffffffPlaneTBD
"colorkey_mode"ENUM{ "disabled", "Y component", "U component" - , "V component", "RGB", “R component", "G component", "B component" }PlaneTBD
"brightness"RANGEMin=0, Max=256 + 255PlaneTBD
"contrast"RANGEMin=0, Max=0x7fffPlaneTBD
"saturation"RANGEMin=0, Max=0x7fffPlaneTBD
exynosCRTC“mode”ENUM{ "normal", "blank" }CRTCTBD
Overlay“zpos”RANGEMin=0, Max=MAX_PLANE-1PlaneTBD
i2c/ch7006_drvGeneric“scale”RANGEMin=0, Max=2ConnectorTBD
TV“mode”ENUM{ "PAL", "PAL-M","PAL-N"}, ”PAL-Nc" - , "PAL-60", "NTSC-M", "NTSC-J" }ConnectorTBD
nouveauNV10 Overlay"colorkey"RANGEMin=0, Max=0x01ffffffPlaneTBD
“contrast”RANGEMin=0, Max=8192-1PlaneTBD
“brightness”RANGEMin=0, Max=1024PlaneTBD
“hue”RANGEMin=0, Max=359PlaneTBD
“saturation”RANGEMin=0, Max=8192-1PlaneTBD
“iturbt_709”RANGEMin=0, Max=1PlaneTBD
Nv04 Overlay“colorkey”RANGEMin=0, Max=0x01ffffffPlaneTBD
“brightness”RANGEMin=0, Max=1024PlaneTBD
Display“dithering mode”ENUM{ "auto", "off", "on" }ConnectorTBD
“dithering depth”ENUM{ "auto", "off", "on", "static 2x2", "dynamic 2x2", "temporal" }ConnectorTBD
“underscan”ENUM{ "auto", "6 bpc", "8 bpc" }ConnectorTBD
“underscan hborder”RANGEMin=0, Max=128ConnectorTBD
“underscan vborder”RANGEMin=0, Max=128ConnectorTBD
“vibrant hue”RANGEMin=0, Max=180ConnectorTBD
“color vibrance”RANGEMin=0, Max=200ConnectorTBD
omapGeneric“zorder”RANGEMin=0, Max=3CRTC, PlaneTBD
qxlGeneric“hotplug_mode_update"RANGEMin=0, Max=1ConnectorTBD
radeonDVI-I“coherent”RANGEMin=0, Max=1ConnectorTBD
DAC enable load detect“load detection”RANGEMin=0, Max=1ConnectorTBD
TV Standard"tv standard"ENUM{ "ntsc", "pal", "pal-m", "pal-60", "ntsc-j" - , "scart-pal", "pal-cn", "secam" }ConnectorTBD
legacy TMDS PLL detect"tmds_pll"ENUM{ "driver", "bios" }-TBD
Underscan"underscan"ENUM{ "off", "on", "auto" }ConnectorTBD
"underscan hborder"RANGEMin=0, Max=128ConnectorTBD
"underscan vborder"RANGEMin=0, Max=128ConnectorTBD
Audio“audio”ENUM{ "off", "on", "auto" }ConnectorTBD
FMT Dithering“dither”ENUM{ "off", "on" }ConnectorTBD
rcar-duGeneric"alpha"RANGEMin=0, Max=255PlaneTBD
"colorkey"RANGEMin=0, Max=0x01ffffffPlaneTBD
"zpos"RANGEMin=1, Max=7PlaneTBD
-
-
- - - - - Vertical Blanking - - Vertical blanking plays a major role in graphics rendering. To achieve - tear-free display, users must synchronize page flips and/or rendering to - vertical blanking. The DRM API offers ioctls to perform page flips - synchronized to vertical blanking and wait for vertical blanking. - - - The DRM core handles most of the vertical blanking management logic, which - involves filtering out spurious interrupts, keeping race-free blanking - counters, coping with counter wrap-around and resets and keeping use - counts. It relies on the driver to generate vertical blanking interrupts - and optionally provide a hardware vertical blanking counter. Drivers must - implement the following operations. - - - - int (*enable_vblank) (struct drm_device *dev, int crtc); -void (*disable_vblank) (struct drm_device *dev, int crtc); - - Enable or disable vertical blanking interrupts for the given CRTC. - - - - u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); - - Retrieve the value of the vertical blanking counter for the given - CRTC. If the hardware maintains a vertical blanking counter its value - should be returned. Otherwise drivers can use the - drm_vblank_count helper function to handle this - operation. - - - - - Drivers must initialize the vertical blanking handling core with a call to - drm_vblank_init in their - load operation. - - - Vertical blanking interrupts can be enabled by the DRM core or by drivers - themselves (for instance to handle page flipping operations). The DRM core - maintains a vertical blanking use count to ensure that the interrupts are - not disabled while a user still needs them. To increment the use count, - drivers call drm_vblank_get. Upon return vertical - blanking interrupts are guaranteed to be enabled. - - - To decrement the use count drivers call - drm_vblank_put. Only when the use count drops to zero - will the DRM core disable the vertical blanking interrupts after a delay - by scheduling a timer. The delay is accessible through the vblankoffdelay - module parameter or the drm_vblank_offdelay global - variable and expressed in milliseconds. Its default value is 5000 ms. - Zero means never disable, and a negative value means disable immediately. - Drivers may override the behaviour by setting the - drm_device - vblank_disable_immediate flag, which when set - causes vblank interrupts to be disabled immediately regardless of the - drm_vblank_offdelay value. The flag should only be set if there's a - properly working hardware vblank counter present. - - - When a vertical blanking interrupt occurs drivers only need to call the - drm_handle_vblank function to account for the - interrupt. - - - Resources allocated by drm_vblank_init must be freed - with a call to drm_vblank_cleanup in the driver - unload operation handler. - - - Vertical Blanking and Interrupt Handling Functions Reference -!Edrivers/gpu/drm/drm_irq.c -!Finclude/drm/drmP.h drm_crtc_vblank_waitqueue - - - - - - - Open/Close, File Operations and IOCTLs - - Open and Close - int (*firstopen) (struct drm_device *); -void (*lastclose) (struct drm_device *); -int (*open) (struct drm_device *, struct drm_file *); -void (*preclose) (struct drm_device *, struct drm_file *); -void (*postclose) (struct drm_device *, struct drm_file *); - Open and close handlers. None of those methods are mandatory. - - - The firstopen method is called by the DRM core - for legacy UMS (User Mode Setting) drivers only when an application - opens a device that has no other opened file handle. UMS drivers can - implement it to acquire device resources. KMS drivers can't use the - method and must acquire resources in the load - method instead. - - - Similarly the lastclose method is called when - the last application holding a file handle opened on the device closes - it, for both UMS and KMS drivers. Additionally, the method is also - called at module unload time or, for hot-pluggable devices, when the - device is unplugged. The firstopen and - lastclose calls can thus be unbalanced. - - - The open method is called every time the device - is opened by an application. Drivers can allocate per-file private data - in this method and store them in the struct - drm_file driver_priv - field. Note that the open method is called - before firstopen. - - - The close operation is split into preclose and - postclose methods. Drivers must stop and - cleanup all per-file operations in the preclose - method. For instance pending vertical blanking and page flip events must - be cancelled. No per-file operation is allowed on the file handle after - returning from the preclose method. - - - Finally the postclose method is called as the - last step of the close operation, right before calling the - lastclose method if no other open file handle - exists for the device. Drivers that have allocated per-file private data - in the open method should free it here. - - - The lastclose method should restore CRTC and - plane properties to default value, so that a subsequent open of the - device will not inherit state from the previous user. It can also be - used to execute delayed power switching state changes, e.g. in - conjunction with the vga_switcheroo infrastructure (see - ). Beyond that KMS drivers should not - do any further cleanup. Only legacy UMS drivers might need to clean up - device state so that the vga console or an independent fbdev driver - could take over. - - - - File Operations -!Pdrivers/gpu/drm/drm_fops.c file operations -!Edrivers/gpu/drm/drm_fops.c - - - IOCTLs - struct drm_ioctl_desc *ioctls; -int num_ioctls; - Driver-specific ioctls descriptors table. - - Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls - descriptors table is indexed by the ioctl number offset from the base - value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize the - table entries. - - - DRM_IOCTL_DEF_DRV(ioctl, func, flags) - - ioctl is the ioctl name. Drivers must define - the DRM_##ioctl and DRM_IOCTL_##ioctl macros to the ioctl number - offset from DRM_COMMAND_BASE and the ioctl number respectively. The - first macro is private to the device while the second must be exposed - to userspace in a public header. - - - func is a pointer to the ioctl handler function - compatible with the drm_ioctl_t type. - typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - - flags is a bitmask combination of the following - values. It restricts how the ioctl is allowed to be called. - - - DRM_AUTH - Only authenticated callers allowed - - - DRM_MASTER - The ioctl can only be called on the master file - handle - - - DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed - - - DRM_CONTROL_ALLOW - The ioctl can only be called on a control - device - - - DRM_UNLOCKED - The ioctl handler will be called without locking - the DRM global mutex. This is the enforced default for kms drivers - (i.e. using the DRIVER_MODESET flag) and hence shouldn't be used - any more for new drivers. - - - - -!Edrivers/gpu/drm/drm_ioctl.c - - - - Legacy Support Code - - The section very briefly covers some of the old legacy support code which - is only used by old DRM drivers which have done a so-called shadow-attach - to the underlying device instead of registering as a real driver. This - also includes some of the old generic buffer management and command - submission code. Do not use any of this in new and modern drivers. - - - - Legacy Suspend/Resume - - The DRM core provides some suspend/resume code, but drivers wanting full - suspend/resume support should provide save() and restore() functions. - These are called at suspend, hibernate, or resume time, and should perform - any state save or restore required by your device across suspend or - hibernate states. - - int (*suspend) (struct drm_device *, pm_message_t state); - int (*resume) (struct drm_device *); - - Those are legacy suspend and resume methods which - only work with the legacy shadow-attach driver - registration functions. New driver should use the power management - interface provided by their bus type (usually through - the struct device_driver dev_pm_ops) and set - these methods to NULL. - - - - - Legacy DMA Services - - This should cover how DMA mapping etc. is supported by the core. - These functions are deprecated and should not be used. - - - -
- - - - - - - Userland interfaces - - The DRM core exports several interfaces to applications, - generally intended to be used through corresponding libdrm - wrapper functions. In addition, drivers export device-specific - interfaces for use by userspace drivers & device-aware - applications through ioctls and sysfs files. - - - External interfaces include: memory mapping, context management, - DMA operations, AGP management, vblank control, fence - management, memory management, and output management. - - - Cover generic ioctls and sysfs layout here. We only need high-level - info, since man pages should cover the rest. - - - - - - Render nodes - - DRM core provides multiple character-devices for user-space to use. - Depending on which device is opened, user-space can perform a different - set of operations (mainly ioctls). The primary node is always created - and called card<num>. Additionally, a currently - unused control node, called controlD<num> is also - created. The primary node provides all legacy operations and - historically was the only interface used by userspace. With KMS, the - control node was introduced. However, the planned KMS control interface - has never been written and so the control node stays unused to date. - - - With the increased use of offscreen renderers and GPGPU applications, - clients no longer require running compositors or graphics servers to - make use of a GPU. But the DRM API required unprivileged clients to - authenticate to a DRM-Master prior to getting GPU access. To avoid this - step and to grant clients GPU access without authenticating, render - nodes were introduced. Render nodes solely serve render clients, that - is, no modesetting or privileged ioctls can be issued on render nodes. - Only non-global rendering commands are allowed. If a driver supports - render nodes, it must advertise it via the DRIVER_RENDER - DRM driver capability. If not supported, the primary node must be used - for render clients together with the legacy drmAuth authentication - procedure. - - - If a driver advertises render node support, DRM core will create a - separate render node called renderD<num>. There will - be one render node per device. No ioctls except PRIME-related ioctls - will be allowed on this node. Especially GEM_OPEN will be - explicitly prohibited. Render nodes are designed to avoid the - buffer-leaks, which occur if clients guess the flink names or mmap - offsets on the legacy interface. Additionally to this basic interface, - drivers must mark their driver-dependent render-only ioctls as - DRM_RENDER_ALLOW so render clients can use them. Driver - authors must be careful not to allow any privileged ioctls on render - nodes. - - - With render nodes, user-space can now control access to the render node - via basic file-system access-modes. A running graphics server which - authenticates clients on the privileged primary/legacy node is no longer - required. Instead, a client can open the render node and is immediately - granted GPU access. Communication between clients (or servers) is done - via PRIME. FLINK from render node to legacy node is not supported. New - clients must not use the insecure FLINK interface. - - - Besides dropping all modeset/global ioctls, render nodes also drop the - DRM-Master concept. There is no reason to associate render clients with - a DRM-Master as they are independent of any graphics server. Besides, - they must work without any running master, anyway. - Drivers must be able to run without a master object if they support - render nodes. If, on the other hand, a driver requires shared state - between clients which is visible to user-space and accessible beyond - open-file boundaries, they cannot support render nodes. - - - - - - - VBlank event handling - - The DRM core exposes two vertical blank related ioctls: - - - DRM_IOCTL_WAIT_VBLANK - - - This takes a struct drm_wait_vblank structure as its argument, - and it is used to block or request a signal when a specified - vblank event occurs. - - - - - DRM_IOCTL_MODESET_CTL - - - This was only used for user-mode-settind drivers around - modesetting changes to allow the kernel to update the vblank - interrupt after mode setting, since on many devices the vertical - blank counter is reset to 0 at some point during modeset. Modern - drivers should not call this any more since with kernel mode - setting it is a no-op. - - - - - - - - -
- - DRM Drivers - - - - This second part of the GPU Driver Developer's Guide documents driver - code, implementation details and also all the driver-specific userspace - interfaces. Especially since all hardware-acceleration interfaces to - userspace are driver specific for efficiency and other reasons these - interfaces can be rather substantial. Hence every driver has its own - chapter. - - - - - drm/i915 Intel GFX Driver - - The drm/i915 driver supports all (with the exception of some very early - models) integrated GFX chipsets with both Intel display and rendering - blocks. This excludes a set of SoC platforms with an SGX rendering unit, - those have basic support through the gma500 drm driver. - - - Core Driver Infrastructure - - This section covers core driver infrastructure used by both the display - and the GEM parts of the driver. - - - Runtime Power Management -!Pdrivers/gpu/drm/i915/intel_runtime_pm.c runtime pm -!Idrivers/gpu/drm/i915/intel_runtime_pm.c -!Idrivers/gpu/drm/i915/intel_uncore.c - - - Interrupt Handling -!Pdrivers/gpu/drm/i915/i915_irq.c interrupt handling -!Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_init intel_irq_init_hw intel_hpd_init -!Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts -!Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts - - - Intel GVT-g Guest Support(vGPU) -!Pdrivers/gpu/drm/i915/i915_vgpu.c Intel GVT-g guest support -!Idrivers/gpu/drm/i915/i915_vgpu.c - - - - Display Hardware Handling - - This section covers everything related to the display hardware including - the mode setting infrastructure, plane, sprite and cursor handling and - display, output probing and related topics. - - - Mode Setting Infrastructure - - The i915 driver is thus far the only DRM driver which doesn't use the - common DRM helper code to implement mode setting sequences. Thus it - has its own tailor-made infrastructure for executing a display - configuration change. - - - - Frontbuffer Tracking -!Pdrivers/gpu/drm/i915/intel_frontbuffer.c frontbuffer tracking -!Idrivers/gpu/drm/i915/intel_frontbuffer.c -!Fdrivers/gpu/drm/i915/i915_gem.c i915_gem_track_fb - - - Display FIFO Underrun Reporting -!Pdrivers/gpu/drm/i915/intel_fifo_underrun.c fifo underrun handling -!Idrivers/gpu/drm/i915/intel_fifo_underrun.c - - - Plane Configuration - - This section covers plane configuration and composition with the - primary plane, sprites, cursors and overlays. This includes the - infrastructure to do atomic vsync'ed updates of all this state and - also tightly coupled topics like watermark setup and computation, - framebuffer compression and panel self refresh. - - - - Atomic Plane Helpers -!Pdrivers/gpu/drm/i915/intel_atomic_plane.c atomic plane helpers -!Idrivers/gpu/drm/i915/intel_atomic_plane.c - - - Output Probing - - This section covers output probing and related infrastructure like the - hotplug interrupt storm detection and mitigation code. Note that the - i915 driver still uses most of the common DRM helper code for output - probing, so those sections fully apply. - - - - Hotplug -!Pdrivers/gpu/drm/i915/intel_hotplug.c Hotplug -!Idrivers/gpu/drm/i915/intel_hotplug.c - - - High Definition Audio -!Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port -!Idrivers/gpu/drm/i915/intel_audio.c -!Iinclude/drm/i915_component.h - - - Panel Self Refresh PSR (PSR/SRD) -!Pdrivers/gpu/drm/i915/intel_psr.c Panel Self Refresh (PSR/SRD) -!Idrivers/gpu/drm/i915/intel_psr.c - - - Frame Buffer Compression (FBC) -!Pdrivers/gpu/drm/i915/intel_fbc.c Frame Buffer Compression (FBC) -!Idrivers/gpu/drm/i915/intel_fbc.c - - - Display Refresh Rate Switching (DRRS) -!Pdrivers/gpu/drm/i915/intel_dp.c Display Refresh Rate Switching (DRRS) -!Fdrivers/gpu/drm/i915/intel_dp.c intel_dp_set_drrs_state -!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_enable -!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_disable -!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_invalidate -!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_flush -!Fdrivers/gpu/drm/i915/intel_dp.c intel_dp_drrs_init - - - - DPIO -!Pdrivers/gpu/drm/i915/i915_reg.h DPIO - - - - CSR firmware support for DMC -!Pdrivers/gpu/drm/i915/intel_csr.c csr support for dmc -!Idrivers/gpu/drm/i915/intel_csr.c - - - Video BIOS Table (VBT) -!Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT) -!Idrivers/gpu/drm/i915/intel_bios.c -!Idrivers/gpu/drm/i915/intel_vbt_defs.h - - - - - Memory Management and Command Submission - - This sections covers all things related to the GEM implementation in the - i915 driver. - - - Batchbuffer Parsing -!Pdrivers/gpu/drm/i915/i915_cmd_parser.c batch buffer command parser -!Idrivers/gpu/drm/i915/i915_cmd_parser.c - - - Batchbuffer Pools -!Pdrivers/gpu/drm/i915/i915_gem_batch_pool.c batch pool -!Idrivers/gpu/drm/i915/i915_gem_batch_pool.c - - - Logical Rings, Logical Ring Contexts and Execlists -!Pdrivers/gpu/drm/i915/intel_lrc.c Logical Rings, Logical Ring Contexts and Execlists -!Idrivers/gpu/drm/i915/intel_lrc.c - - - Global GTT views -!Pdrivers/gpu/drm/i915/i915_gem_gtt.c Global GTT views -!Idrivers/gpu/drm/i915/i915_gem_gtt.c - - - GTT Fences and Swizzling -!Idrivers/gpu/drm/i915/i915_gem_fence.c - - Global GTT Fence Handling -!Pdrivers/gpu/drm/i915/i915_gem_fence.c fence register handling - - - Hardware Tiling and Swizzling Details -!Pdrivers/gpu/drm/i915/i915_gem_fence.c tiling swizzling details - - - - Object Tiling IOCTLs -!Idrivers/gpu/drm/i915/i915_gem_tiling.c -!Pdrivers/gpu/drm/i915/i915_gem_tiling.c buffer object tiling - - - Buffer Object Eviction - - This section documents the interface functions for evicting buffer - objects to make space available in the virtual gpu address spaces. - Note that this is mostly orthogonal to shrinking buffer objects - caches, which has the goal to make main memory (shared with the gpu - through the unified memory architecture) available. - -!Idrivers/gpu/drm/i915/i915_gem_evict.c - - - Buffer Object Memory Shrinking - - This section documents the interface function for shrinking memory - usage of buffer object caches. Shrinking is used to make main memory - available. Note that this is mostly orthogonal to evicting buffer - objects, which has the goal to make space in gpu virtual address - spaces. - -!Idrivers/gpu/drm/i915/i915_gem_shrinker.c - - - - GuC - - GuC-specific firmware loader -!Pdrivers/gpu/drm/i915/intel_guc_loader.c GuC-specific firmware loader -!Idrivers/gpu/drm/i915/intel_guc_loader.c - - - GuC-based command submission -!Pdrivers/gpu/drm/i915/i915_guc_submission.c GuC-based command submission -!Idrivers/gpu/drm/i915/i915_guc_submission.c - - - GuC Firmware Layout -!Pdrivers/gpu/drm/i915/intel_guc_fwif.h GuC Firmware Layout - - - - - Tracing - - This sections covers all things related to the tracepoints implemented in - the i915 driver. - - - i915_ppgtt_create and i915_ppgtt_release -!Pdrivers/gpu/drm/i915/i915_trace.h i915_ppgtt_create and i915_ppgtt_release tracepoints - - - i915_context_create and i915_context_free -!Pdrivers/gpu/drm/i915/i915_trace.h i915_context_create and i915_context_free tracepoints - - - switch_mm -!Pdrivers/gpu/drm/i915/i915_trace.h switch_mm tracepoint - - - - -!Cdrivers/gpu/drm/i915/i915_irq.c - - - - vga_switcheroo - -!Pdrivers/gpu/vga/vga_switcheroo.c Overview - - - - Modes of Use - - Manual switching and manual power control -!Pdrivers/gpu/vga/vga_switcheroo.c Manual switching and manual power control - - - Driver power control -!Pdrivers/gpu/vga/vga_switcheroo.c Driver power control - - - - - API - - Public functions -!Edrivers/gpu/vga/vga_switcheroo.c - - - Public structures -!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler -!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops - - - Public constants -!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler_flags_t -!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id -!Finclude/linux/vga_switcheroo.h vga_switcheroo_state - - - Private structures -!Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv -!Fdrivers/gpu/vga/vga_switcheroo.c vga_switcheroo_client - - - - - Handlers - - apple-gmux Handler -!Pdrivers/platform/x86/apple-gmux.c Overview -!Pdrivers/platform/x86/apple-gmux.c Interrupt - - Graphics mux -!Pdrivers/platform/x86/apple-gmux.c Graphics mux - - - Power control -!Pdrivers/platform/x86/apple-gmux.c Power control - - - Backlight control -!Pdrivers/platform/x86/apple-gmux.c Backlight control - - - Public functions -!Iinclude/linux/apple-gmux.h - - - - -!Cdrivers/gpu/vga/vga_switcheroo.c -!Cinclude/linux/vga_switcheroo.h -!Cdrivers/platform/x86/apple-gmux.c - - - diff --git a/MAINTAINERS b/MAINTAINERS index ce9c23dd02c6..dddf1944999a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3858,7 +3858,6 @@ F: Documentation/devicetree/bindings/display/ F: Documentation/devicetree/bindings/gpu/ F: Documentation/devicetree/bindings/video/ F: Documentation/gpu/ -F: Documentation/DocBook/gpu.* F: include/drm/ F: include/uapi/drm/ -- cgit v1.3-14-g43fede From b2f8c3d5e24d4de8166b68dcde457c093990815d Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Thu, 19 May 2016 15:11:03 +0200 Subject: ARM: at91: Documentation: update the sama5d2 entry Update the Atmel SoC entry for SAMA5D2 with all the product variants. Add the datasheet web link, now that it's available, for instant access to full product documentation. Signed-off-by: Nicolas Ferre Signed-off-by: Alexandre Belloni --- Documentation/arm/Atmel/README | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Atmel/README index 0931cf7e2e56..6ca78f818dbf 100644 --- a/Documentation/arm/Atmel/README +++ b/Documentation/arm/Atmel/README @@ -91,9 +91,15 @@ the Atmel website: http://www.atmel.com. http://www.atmel.com/Images/Atmel-11238-32-bit-Cortex-A5-Microcontroller-SAMA5D4_Datasheet.pdf - sama5d2 family - - sama5d27 + - sama5d21 + - sama5d22 + - sama5d23 + - sama5d24 + - sama5d26 + - sama5d27 (device superset) + - sama5d28 (device superset + environmental monitors) + Datasheet - Coming soon + http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf Linux kernel information -- cgit v1.3-14-g43fede From 83ce0efc12811c1b11f71a8164949ff4f6117054 Mon Sep 17 00:00:00 2001 From: Al Stone Date: Mon, 13 Jun 2016 15:41:55 -0600 Subject: ARM64: ACPI: Update documentation for latest specification version The ACPI 6.1 specification was recently released at the end of January 2016, but the arm64 kernel documentation for the use of ACPI was written for the 5.1 version of the spec. There were significant additions to the spec that had not yet been mentioned -- for example, the 6.0 mechanisms added to make it easier to define processors and low power idle states, as well as the 6.1 addition allowing regular interrupts (not just from GPIO) be used to signal ACPI general purpose events. This patch reflects going back through and examining the specs in detail and updating content appropriately. Whilst there, a few odds and ends of typos were caught as well. This brings the documentation up to date with ACPI 6.1 for arm64. Signed-off-by: Al Stone Acked-by: Lorenzo Pieralisi Reviewed-by: Hanjun Guo Reviewed-by: Roy Franz Signed-off-by: Catalin Marinas --- Documentation/arm64/acpi_object_usage.txt | 343 ++++++++++++++++-------------- Documentation/arm64/arm-acpi.txt | 40 ++-- 2 files changed, 213 insertions(+), 170 deletions(-) (limited to 'Documentation') diff --git a/Documentation/arm64/acpi_object_usage.txt b/Documentation/arm64/acpi_object_usage.txt index a6e1a1805e51..c77010c5c1f0 100644 --- a/Documentation/arm64/acpi_object_usage.txt +++ b/Documentation/arm64/acpi_object_usage.txt @@ -13,14 +13,14 @@ For ACPI on arm64, tables also fall into the following categories: -- Required: DSDT, FADT, GTDT, MADT, MCFG, RSDP, SPCR, XSDT - -- Recommended: BERT, EINJ, ERST, HEST, SSDT + -- Recommended: BERT, EINJ, ERST, HEST, PCCT, SSDT - -- Optional: BGRT, CPEP, CSRT, DRTM, ECDT, FACS, FPDT, MCHI, MPST, - MSCT, RASF, SBST, SLIT, SPMI, SRAT, TCPA, TPM2, UEFI - - -- Not supported: BOOT, DBG2, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, - LPIT, MSDM, RSDT, SLIC, WAET, WDAT, WDRT, WPBT + -- Optional: BGRT, CPEP, CSRT, DBG2, DRTM, ECDT, FACS, FPDT, IORT, + MCHI, MPST, MSCT, NFIT, PMTT, RASF, SBST, SLIT, SPMI, SRAT, STAO, + TCPA, TPM2, UEFI, XENV + -- Not supported: BOOT, DBGP, DMAR, ETDT, HPET, IBFT, IVRS, LPIT, + MSDM, OEMx, PSDT, RSDT, SLIC, WAET, WDAT, WDRT, WPBT Table Usage for ARMv8 Linux ----- ---------------------------------------------------------------- @@ -50,7 +50,8 @@ CSRT Signature Reserved (signature == "CSRT") DBG2 Signature Reserved (signature == "DBG2") == DeBuG port table 2 == - Microsoft only table, will not be supported. + License has changed and should be usable. Optional if used instead + of earlycon= on the command line. DBGP Signature Reserved (signature == "DBGP") == DeBuG Port table == @@ -133,10 +134,11 @@ GTDT Section 5.2.24 (signature == "GTDT") HEST Section 18.3.2 (signature == "HEST") == Hardware Error Source Table == - Until further error source types are defined, use only types 6 (AER - Root Port), 7 (AER Endpoint), 8 (AER Bridge), or 9 (Generic Hardware - Error Source). Firmware first error handling is possible if and only - if Trusted Firmware is being used on arm64. + ARM-specific error sources have been defined; please use those or the + PCI types such as type 6 (AER Root Port), 7 (AER Endpoint), or 8 (AER + Bridge), or use type 9 (Generic Hardware Error Source). Firmware first + error handling is possible if and only if Trusted Firmware is being + used on arm64. Must be supplied if RAS support is provided by the platform. It is recommended this table be supplied. @@ -149,20 +151,30 @@ IBFT Signature Reserved (signature == "IBFT") == iSCSI Boot Firmware Table == Microsoft defined table, support TBD. +IORT Signature Reserved (signature == "IORT") + == Input Output Remapping Table == + arm64 only table, required in order to describe IO topology, SMMUs, + and GIC ITSs, and how those various components are connected together, + such as identifying which components are behind which SMMUs/ITSs. + This table will only be required on certain SBSA platforms (e.g., + when using GICv3-ITS and an SMMU); on SBSA Level 0 platforms, it + remains optional. + IVRS Signature Reserved (signature == "IVRS") == I/O Virtualization Reporting Structure == x86_64 (AMD) only table, will not be supported. LPIT Signature Reserved (signature == "LPIT") == Low Power Idle Table == - x86 only table as of ACPI 5.1; future versions have been adapted for - use with ARM and will be recommended in order to support ACPI power - management. + x86 only table as of ACPI 5.1; starting with ACPI 6.0, processor + descriptions and power states on ARM platforms should use the DSDT + and define processor container devices (_HID ACPI0010, Section 8.4, + and more specifically 8.4.3 and and 8.4.4). MADT Section 5.2.12 (signature == "APIC") == Multiple APIC Description Table == Required for arm64. Only the GIC interrupt controller structures - should be used (types 0xA - 0xE). + should be used (types 0xA - 0xF). MCFG Signature Reserved (signature == "MCFG") == Memory-mapped ConFiGuration space == @@ -176,14 +188,38 @@ MPST Section 5.2.21 (signature == "MPST") == Memory Power State Table == Optional, not currently supported. +MSCT Section 5.2.19 (signature == "MSCT") + == Maximum System Characteristic Table == + Optional, not currently supported. + MSDM Signature Reserved (signature == "MSDM") == Microsoft Data Management table == Microsoft only table, will not be supported. -MSCT Section 5.2.19 (signature == "MSCT") - == Maximum System Characteristic Table == +NFIT Section 5.2.25 (signature == "NFIT") + == NVDIMM Firmware Interface Table == + Optional, not currently supported. + +OEMx Signature of "OEMx" only + == OEM Specific Tables == + All tables starting with a signature of "OEM" are reserved for OEM + use. Since these are not meant to be of general use but are limited + to very specific end users, they are not recommended for use and are + not supported by the kernel for arm64. + +PCCT Section 14.1 (signature == "PCCT) + == Platform Communications Channel Table == + Recommend for use on arm64; use of PCC is recommended when using CPPC + to control performance and power for platform processors. + +PMTT Section 5.2.21.12 (signature == "PMTT") + == Platform Memory Topology Table == Optional, not currently supported. +PSDT Section 5.2.11.3 (signature == "PSDT") + == Persistent System Description Table == + Obsolete table, will not be supported. + RASF Section 5.2.20 (signature == "RASF") == RAS Feature table == Optional, not currently supported. @@ -195,7 +231,7 @@ RSDP Section 5.2.5 (signature == "RSD PTR") RSDT Section 5.2.7 (signature == "RSDT") == Root System Description Table == Since this table can only provide 32-bit addresses, it is deprecated - on arm64, and will not be used. + on arm64, and will not be used. If provided, it will be ignored. SBST Section 5.2.14 (signature == "SBST") == Smart Battery Subsystem Table == @@ -220,7 +256,7 @@ SPMI Signature Reserved (signature == "SPMI") SRAT Section 5.2.16 (signature == "SRAT") == System Resource Affinity Table == Optional, but if used, only the GICC Affinity structures are read. - To support NUMA, this table is required. + To support arm64 NUMA, this table is required. SSDT Section 5.2.11.2 (signature == "SSDT") == Secondary System Description Table == @@ -235,6 +271,11 @@ SSDT Section 5.2.11.2 (signature == "SSDT") These tables are optional, however. ACPI tables should contain only one DSDT but can contain many SSDTs. +STAO Signature Reserved (signature == "STAO") + == _STA Override table == + Optional, but only necessary in virtualized environments in order to + hide devices from guest OSs. + TCPA Signature Reserved (signature == "TCPA") == Trusted Computing Platform Alliance table == Optional, not currently supported, and may need changes to fully @@ -266,6 +307,10 @@ WPBT Signature Reserved (signature == "WPBT") == Windows Platform Binary Table == Microsoft only table, will not be supported. +XENV Signature Reserved (signature == "XENV") + == Xen project table == + Optional, used only by Xen at present. + XSDT Section 5.2.8 (signature == "XSDT") == eXtended System Description Table == Required for arm64. @@ -273,44 +318,46 @@ XSDT Section 5.2.8 (signature == "XSDT") ACPI Objects ------------ -The expectations on individual ACPI objects are discussed in the list that -follows: +The expectations on individual ACPI objects that are likely to be used are +shown in the list that follows; any object not explicitly mentioned below +should be used as needed for a particular platform or particular subsystem, +such as power management or PCI. Name Section Usage for ARMv8 Linux ---- ------------ ------------------------------------------------- -_ADR 6.1.1 Use as needed. - -_BBN 6.5.5 Use as needed; PCI-specific. +_CCA 6.2.17 This method must be defined for all bus masters + on arm64 -- there are no assumptions made about + whether such devices are cache coherent or not. + The _CCA value is inherited by all descendants of + these devices so it does not need to be repeated. + Without _CCA on arm64, the kernel does not know what + to do about setting up DMA for the device. -_BDN 6.5.3 Optional; not likely to be used on arm64. + NB: this method provides default cache coherency + attributes; the presence of an SMMU can be used to + modify that, however. For example, a master could + default to non-coherent, but be made coherent with + the appropriate SMMU configuration (see Table 17 of + the IORT specification, ARM Document DEN 0049B). -_CCA 6.2.17 This method should be defined for all bus masters - on arm64. While cache coherency is assumed, making - it explicit ensures the kernel will set up DMA as - it should. +_CID 6.1.2 Use as needed, see also _HID. -_CDM 6.2.1 Optional, to be used only for processor devices. +_CLS 6.1.3 Use as needed, see also _HID. -_CID 6.1.2 Use as needed. - -_CLS 6.1.3 Use as needed. +_CPC 8.4.7.1 Use as needed, power management specific. CPPC is + recommended on arm64. _CRS 6.2.2 Required on arm64. -_DCK 6.5.2 Optional; not likely to be used on arm64. +_CSD 8.4.2.2 Use as needed, used only in conjunction with _CST. + +_CST 8.4.2.1 Low power idle states (8.4.4) are recommended instead + of C-states. _DDN 6.1.4 This field can be used for a device name. However, it is meant for DOS device names (e.g., COM1), so be careful of its use across OSes. -_DEP 6.5.8 Use as needed. - -_DIS 6.2.3 Optional, for power management use. - -_DLM 5.7.5 Optional. - -_DMA 6.2.4 Optional. - _DSD 6.2.5 To be used with caution. If this object is used, try to use it within the constraints already defined by the Device Properties UUID. Only in rare circumstances @@ -325,20 +372,10 @@ _DSD 6.2.5 To be used with caution. If this object is used, try with the UEFI Forum; this may cause some iteration as more than one OS will be registering entries. -_DSM Do not use this method. It is not standardized, the +_DSM 9.1.1 Do not use this method. It is not standardized, the return values are not well documented, and it is currently a frequent source of error. -_DSW 7.2.1 Use as needed; power management specific. - -_EDL 6.3.1 Optional. - -_EJD 6.3.2 Optional. - -_EJx 6.3.3 Optional. - -_FIX 6.2.7 x86 specific, not used on arm64. - \_GL 5.7.1 This object is not to be used in hardware reduced mode, and therefore should not be used on arm64. @@ -349,35 +386,22 @@ _GLK 6.5.7 This object requires a global lock be defined; there \_GPE 5.3.1 This namespace is for x86 use only. Do not use it on arm64. -_GSB 6.2.7 Optional. - -_HID 6.1.5 Use as needed. This is the primary object to use in - device probing, though _CID and _CLS may also be used. - -_HPP 6.2.8 Optional, PCI specific. - -_HPX 6.2.9 Optional, PCI specific. - -_HRV 6.1.6 Optional, use as needed to clarify device behavior; in - some cases, this may be easier to use than _DSD. +_HID 6.1.5 This is the primary object to use in device probing, + though _CID and _CLS may also be used. _INI 6.5.1 Not required, but can be useful in setting up devices when UEFI leaves them in a state that may not be what the driver expects before it starts probing. -_IRC 7.2.15 Use as needed; power management specific. - -_LCK 6.3.4 Optional. - -_MAT 6.2.10 Optional; see also the MADT. +_LPI 8.4.4.3 Recommended for use with processor definitions (_HID + ACPI0010) on arm64. See also _RDI. -_MLS 6.1.7 Optional, but highly recommended for use in - internationalization. +_MLS 6.1.7 Highly recommended for use in internationalization. -_OFF 7.1.2 It is recommended to define this method for any device +_OFF 7.2.2 It is recommended to define this method for any device that can be turned on or off. -_ON 7.1.3 It is recommended to define this method for any device +_ON 7.2.3 It is recommended to define this method for any device that can be turned on or off. \_OS 5.7.3 This method will return "Linux" by default (this is @@ -398,122 +422,107 @@ _OSC 6.2.11 This method can be a global method in ACPI (i.e., by the kernel community, then register it with the UEFI Forum. -\_OSI 5.7.2 Deprecated on ARM64. Any invocation of this method - will print a warning on the console and return false. - That is, as far as ACPI firmware is concerned, _OSI - cannot be used to determine what sort of system is - being used or what functionality is provided. The - _OSC method is to be used instead. - -_OST 6.3.5 Optional. +\_OSI 5.7.2 Deprecated on ARM64. As far as ACPI firmware is + concerned, _OSI is not to be used to determine what + sort of system is being used or what functionality + is provided. The _OSC method is to be used instead. _PDC 8.4.1 Deprecated, do not use on arm64. \_PIC 5.8.1 The method should not be used. On arm64, the only interrupt model available is GIC. -_PLD 6.1.8 Optional. - \_PR 5.3.1 This namespace is for x86 use only on legacy systems. Do not use it on arm64. -_PRS 6.2.12 Optional. - _PRT 6.2.13 Required as part of the definition of all PCI root devices. -_PRW 7.2.13 Use as needed; power management specific. - -_PRx 7.2.8-11 Use as needed; power management specific. If _PR0 is +_PRx 7.3.8-11 Use as needed; power management specific. If _PR0 is defined, _PR3 must also be defined. -_PSC 7.2.6 Use as needed; power management specific. - -_PSE 7.2.7 Use as needed; power management specific. - -_PSW 7.2.14 Use as needed; power management specific. - -_PSx 7.2.2-5 Use as needed; power management specific. If _PS0 is +_PSx 7.3.2-5 Use as needed; power management specific. If _PS0 is defined, _PS3 must also be defined. If clocks or regulators need adjusting to be consistent with power usage, change them in these methods. -\_PTS 7.3.1 Use as needed; power management specific. - -_PXM 6.2.14 Optional. - -_REG 6.5.4 Use as needed. +_RDI 8.4.4.4 Recommended for use with processor definitions (_HID + ACPI0010) on arm64. This should only be used in + conjunction with _LPI. \_REV 5.7.4 Always returns the latest version of ACPI supported. -_RMV 6.3.6 Optional. - \_SB 5.3.1 Required on arm64; all devices must be defined in this namespace. -_SEG 6.5.6 Use as needed; PCI-specific. - -\_SI 5.3.1, Optional. - 9.1 - -_SLI 6.2.15 Optional; recommended when SLIT table is in use. +_SLI 6.2.15 Use is recommended when SLIT table is in use. _STA 6.3.7, It is recommended to define this method for any device - 7.1.4 that can be turned on or off. + 7.2.4 that can be turned on or off. See also the STAO table + that provides overrides to hide devices in virtualized + environments. -_SRS 6.2.16 Optional; see also _PRS. +_SRS 6.2.16 Use as needed; see also _PRS. _STR 6.1.10 Recommended for conveying device names to end users; this is preferred over using _DDN. _SUB 6.1.9 Use as needed; _HID or _CID are preferred. -_SUN 6.1.11 Optional. - -\_Sx 7.3.2 Use as needed; power management specific. - -_SxD 7.2.16-19 Use as needed; power management specific. - -_SxW 7.2.20-24 Use as needed; power management specific. +_SUN 6.1.11 Use as needed, but recommended. -_SWS 7.3.3 Use as needed; power management specific; this may +_SWS 7.4.3 Use as needed; power management specific; this may require specification changes for use on arm64. -\_TTS 7.3.4 Use as needed; power management specific. - -\_TZ 5.3.1 Optional. - _UID 6.1.12 Recommended for distinguishing devices of the same class; define it if at all possible. -\_WAK 7.3.5 Use as needed; power management specific. + ACPI Event Model ---------------- Do not use GPE block devices; these are not supported in the hardware reduced profile used by arm64. Since there are no GPE blocks defined for use on ARM -platforms, GPIO-signaled interrupts should be used for creating system events. +platforms, ACPI events must be signaled differently. + +There are two options: GPIO-signaled interrupts (Section 5.6.5), and +interrupt-signaled events (Section 5.6.9). Interrupt-signaled events are a +new feature in the ACPI 6.1 specification. Either -- or both -- can be used +on a given platform, and which to use may be dependent of limitations in any +given SoC. If possible, interrupt-signaled events are recommended. ACPI Processor Control ---------------------- -Section 8 of the ACPI specification is currently undergoing change that -should be completed in the 6.0 version of the specification. Processor -performance control will be handled differently for arm64 at that point -in time. Processor aggregator devices (section 8.5) will not be used, -for example, but another similar mechanism instead. - -While UEFI constrains what we can say until the release of 6.0, it is -recommended that CPPC (8.4.5) be used as the primary model. This will -still be useful into the future. C-states and P-states will still be -provided, but most of the current design work appears to favor CPPC. +Section 8 of the ACPI specification changed significantly in version 6.0. +Processors should now be defined as Device objects with _HID ACPI0007; do +not use the deprecated Processor statement in ASL. All multiprocessor systems +should also define a hierarchy of processors, done with Processor Container +Devices (see Section 8.4.3.1, _HID ACPI0010); do not use processor aggregator +devices (Section 8.5) to describe processor topology. Section 8.4 of the +specification describes the semantics of these object definitions and how +they interrelate. + +Most importantly, the processor hierarchy defined also defines the low power +idle states that are available to the platform, along with the rules for +determining which processors can be turned on or off and the circumstances +that control that. Without this information, the processors will run in +whatever power state they were left in by UEFI. + +Note too, that the processor Device objects defined and the entries in the +MADT for GICs are expected to be in synchronization. The _UID of the Device +object must correspond to processor IDs used in the MADT. + +It is recommended that CPPC (8.4.5) be used as the primary model for processor +performance control on arm64. C-states and P-states may become available at +some point in the future, but most current design work appears to favor CPPC. Further, it is essential that the ARMv8 SoC provide a fully functional implementation of PSCI; this will be the only mechanism supported by ACPI -to control CPU power state (including secondary CPU booting). - -More details will be provided on the release of the ACPI 6.0 specification. +to control CPU power state. Booting of secondary CPUs using the ACPI +parking protocol is possible, but discouraged, since only PSCI is supported +for ARM servers. ACPI System Address Map Interfaces @@ -535,21 +544,25 @@ used to indicate fatal errors that cannot be corrected, and require immediate attention. Since there is no direct equivalent of the x86 SCI or NMI, arm64 handles -these slightly differently. The SCI is handled as a normal GPIO-signaled -interrupt; given that these are corrected (or correctable) errors being -reported, this is sufficient. The NMI is emulated as the highest priority -GPIO-signaled interrupt possible. This implies some caution must be used -since there could be interrupts at higher privilege levels or even interrupts -at the same priority as the emulated NMI. In Linux, this should not be the -case but one should be aware it could happen. +these slightly differently. The SCI is handled as a high priority interrupt; +given that these are corrected (or correctable) errors being reported, this +is sufficient. The NMI is emulated as the highest priority interrupt +possible. This implies some caution must be used since there could be +interrupts at higher privilege levels or even interrupts at the same priority +as the emulated NMI. In Linux, this should not be the case but one should +be aware it could happen. ACPI Objects Not Supported on ARM64 ----------------------------------- While this may change in the future, there are several classes of objects that can be defined, but are not currently of general interest to ARM servers. +Some of these objects have x86 equivalents, and may actually make sense in ARM +servers. However, there is either no hardware available at present, or there +may not even be a non-ARM implementation yet. Hence, they are not currently +supported. -These are not supported: +The following classes of objects are not supported: -- Section 9.2: ambient light sensor devices @@ -571,16 +584,6 @@ These are not supported: -- Section 9.18: time and alarm devices (see 9.15) - -ACPI Objects Not Yet Implemented --------------------------------- -While these objects have x86 equivalents, and they do make some sense in ARM -servers, there is either no hardware available at present, or in some cases -there may not yet be a non-ARM implementation. Hence, they are currently not -implemented though that may change in the future. - -Not yet implemented are: - -- Section 10: power source and power meter devices -- Section 11: thermal management @@ -589,5 +592,31 @@ Not yet implemented are: -- Section 13: SMBus interfaces - -- Section 17: NUMA support (prototypes have been submitted for - review) + +This also means that there is no support for the following objects: + +Name Section Name Section +---- ------------ ---- ------------ +_ALC 9.3.4 _FDM 9.10.3 +_ALI 9.3.2 _FIX 6.2.7 +_ALP 9.3.6 _GAI 10.4.5 +_ALR 9.3.5 _GHL 10.4.7 +_ALT 9.3.3 _GTM 9.9.2.1.1 +_BCT 10.2.2.10 _LID 9.5.1 +_BDN 6.5.3 _PAI 10.4.4 +_BIF 10.2.2.1 _PCL 10.3.2 +_BIX 10.2.2.1 _PIF 10.3.3 +_BLT 9.2.3 _PMC 10.4.1 +_BMA 10.2.2.4 _PMD 10.4.8 +_BMC 10.2.2.12 _PMM 10.4.3 +_BMD 10.2.2.11 _PRL 10.3.4 +_BMS 10.2.2.5 _PSR 10.3.1 +_BST 10.2.2.6 _PTP 10.4.2 +_BTH 10.2.2.7 _SBS 10.1.3 +_BTM 10.2.2.9 _SHL 10.4.6 +_BTP 10.2.2.8 _STM 9.9.2.1.1 +_DCK 6.5.2 _UPD 9.16.1 +_EC 12.12 _UPP 9.16.2 +_FDE 9.10.1 _WPC 10.5.2 +_FDI 9.10.2 _WPP 10.5.3 + diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt index 570a4f8e1a01..1a74a041a443 100644 --- a/Documentation/arm64/arm-acpi.txt +++ b/Documentation/arm64/arm-acpi.txt @@ -34,7 +34,7 @@ of the summary text almost directly, to be honest. The short form of the rationale for ACPI on ARM is: --- ACPI’s bytecode (AML) allows the platform to encode hardware behavior, +-- ACPI’s byte code (AML) allows the platform to encode hardware behavior, while DT explicitly does not support this. For hardware vendors, being able to encode behavior is a key tool used in supporting operating system releases on new hardware. @@ -57,11 +57,11 @@ The short form of the rationale for ACPI on ARM is: -- The new ACPI governance process works well and Linux is now at the same table as hardware vendors and other OS vendors. In fact, there is no - longer any reason to feel that ACPI is only belongs to Windows or that + longer any reason to feel that ACPI only belongs to Windows or that Linux is in any way secondary to Microsoft in this arena. The move of ACPI governance into the UEFI forum has significantly opened up the specification development process, and currently, a large portion of the - changes being made to ACPI is being driven by Linux. + changes being made to ACPI are being driven by Linux. Key to the use of ACPI is the support model. For servers in general, the responsibility for hardware behaviour cannot solely be the domain of the @@ -110,7 +110,7 @@ ACPI support in drivers and subsystems for ARMv8 should never be mutually exclusive with DT support at compile time. At boot time the kernel will only use one description method depending on -parameters passed from the bootloader (including kernel bootargs). +parameters passed from the boot loader (including kernel bootargs). Regardless of whether DT or ACPI is used, the kernel must always be capable of booting with either scheme (in kernels with both schemes enabled at compile @@ -159,7 +159,7 @@ Further, the ACPI core will only use the 64-bit address fields in the FADT (Fixed ACPI Description Table). Any 32-bit address fields in the FADT will be ignored on arm64. -Hardware reduced mode (see Section 4.1 of the ACPI 5.1 specification) will +Hardware reduced mode (see Section 4.1 of the ACPI 6.1 specification) will be enforced by the ACPI core on arm64. Doing so allows the ACPI core to run less complex code since it no longer has to provide support for legacy hardware from other architectures. Any fields that are not to be used for @@ -167,7 +167,7 @@ hardware reduced mode must be set to zero. For the ACPI core to operate properly, and in turn provide the information the kernel needs to configure devices, it expects to find the following -tables (all section numbers refer to the ACPI 5.1 specfication): +tables (all section numbers refer to the ACPI 6.1 specification): -- RSDP (Root System Description Pointer), section 5.2.5 @@ -185,9 +185,23 @@ tables (all section numbers refer to the ACPI 5.1 specfication): -- If PCI is supported, the MCFG (Memory mapped ConFiGuration Table), section 5.2.6, specifically Table 5-31. + -- If booting without a console= kernel parameter is + supported, the SPCR (Serial Port Console Redirection table), + section 5.2.6, specifically Table 5-31. + + -- If necessary to describe the I/O topology, SMMUs and GIC ITSs, + the IORT (Input Output Remapping Table, section 5.2.6, specifically + Table 5-31). + + -- If NUMA is supported, the SRAT (System Resource Affinity Table) + and SLIT (System Locality distance Information Table), sections + 5.2.16 and 5.2.17, respectively. + If the above tables are not all present, the kernel may or may not be able to boot properly since it may not be able to configure all of the -devices available. +devices available. This list of tables is not meant to be all inclusive; +in some environments other tables may be needed (e.g., any of the APEI +tables from section 18) to support specific functionality. ACPI Detection @@ -198,7 +212,7 @@ the device structure. This is detailed further in the "Driver Recommendations" section. In non-driver code, if the presence of ACPI needs to be detected at -runtime, then check the value of acpi_disabled. If CONFIG_ACPI is not +run time, then check the value of acpi_disabled. If CONFIG_ACPI is not set, acpi_disabled will always be 1. @@ -233,7 +247,7 @@ that looks like this: Name(KEY0, "value0"). An ACPI device driver would then retrieve the value of the property by evaluating the KEY0 object. However, using Name() this way has multiple problems: (1) ACPI limits names ("KEY0") to four characters unlike DT; (2) there is no industry -wide registry that maintains a list of names, minimzing re-use; (3) +wide registry that maintains a list of names, minimizing re-use; (3) there is also no registry for the definition of property values ("value0"), again making re-use difficult; and (4) how does one maintain backward compatibility as new hardware comes out? The _DSD method was created @@ -434,7 +448,8 @@ The ACPI specification changes regularly. During the year 2014, for instance, version 5.1 was released and version 6.0 substantially completed, with most of the changes being driven by ARM-specific requirements. Proposed changes are presented and discussed in the ASWG (ACPI Specification Working Group) which -is a part of the UEFI Forum. +is a part of the UEFI Forum. The current version of the ACPI specification +is 6.1 release in January 2016. Participation in this group is open to all UEFI members. Please see http://www.uefi.org/workinggroup for details on group membership. @@ -443,7 +458,7 @@ It is the intent of the ARMv8 ACPI kernel code to follow the ACPI specification as closely as possible, and to only implement functionality that complies with the released standards from UEFI ASWG. As a practical matter, there will be vendors that provide bad ACPI tables or violate the standards in some way. -If this is because of errors, quirks and fixups may be necessary, but will +If this is because of errors, quirks and fix-ups may be necessary, but will be avoided if possible. If there are features missing from ACPI that preclude it from being used on a platform, ECRs (Engineering Change Requests) should be submitted to ASWG and go through the normal approval process; for those that @@ -480,8 +495,7 @@ References Software on ARM Platforms", dated 16 Aug 2014 [2] http://www.secretlab.ca/archives/151, 10 Jan 2015, Copyright (c) 2015, - Linaro Ltd., written by Grant Likely. A copy of the verbatim text (apart - from formatting) is also in Documentation/arm64/why_use_acpi.txt. + Linaro Ltd., written by Grant Likely. [3] AMD ACPI for Seattle platform documentation: http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Seattle_ACPI_Guide.pdf -- cgit v1.3-14-g43fede From a325725633c26aa66ab940f762a6b0778edf76c0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 21 Jun 2016 14:08:33 +0200 Subject: drm: Lobotomize set_busid nonsense for !pci drivers We already have a fallback in place to fill out the unique from dev->unique, which is set to something reasonable in drm_dev_alloc. Which means we only need to have a special set_busid for pci devices, to be able to care the backwards compat code for drm 1.1 around, which libdrm still needs. While developing and testing this patch things blew up in really interesting ways, and the code is rather confusing in naming things between the kernel code, ioctl #defines and libdrm. For the next brave dragon slayer, document all this madness properly in the userspace interface section of gpu.tmpl. v2: Make drm_dev_set_unique static and update kerneldoc. v3: Entire rewrite, plus document what's going on for posterity in the gpu docbook uapi section. v4: Drop accidental amdgpu hunk (Emil). v5: Drop accidental omapdrm vblank counter change (Emil). v6: Rebase on top of the sphinx conversion. Cc: Gustavo Padovan Cc: Emil Velikov Tested-by: Gustavo Padovan (virt_gpu) Reviewed-by: Emil Velikov Signed-off-by: Daniel Vetter --- Documentation/gpu/drm-uapi.rst | 6 +++ drivers/gpu/drm/armada/armada_drv.c | 1 - drivers/gpu/drm/drm_ioctl.c | 58 +++++++++++++++++++++++++ drivers/gpu/drm/drm_platform.c | 18 -------- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 1 - drivers/gpu/drm/imx/imx-drm-core.c | 1 - drivers/gpu/drm/msm/msm_drv.c | 1 - drivers/gpu/drm/nouveau/nouveau_drm.c | 1 - drivers/gpu/drm/omapdrm/omap_drv.c | 1 - drivers/gpu/drm/shmobile/shmob_drm_drv.c | 1 - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 10 ----- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - include/drm/drmP.h | 1 - 17 files changed, 64 insertions(+), 41 deletions(-) (limited to 'Documentation') diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 6da1e77e55fa..a1c6f0103bc4 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -14,6 +14,12 @@ management, and output management. Cover generic ioctls and sysfs layout here. We only need high-level info, since man pages should cover the rest. +libdrm Device Lookup +==================== + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :doc: getunique and setversion story + Render nodes ============ diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index cb21c0b6374a..f5ebdd681445 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -189,7 +189,6 @@ static struct drm_driver armada_drm_driver = { .load = armada_drm_load, .lastclose = armada_drm_lastclose, .unload = armada_drm_unload, - .set_busid = drm_platform_set_busid, .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = armada_drm_enable_vblank, .disable_vblank = armada_drm_disable_vblank, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 1fa7619face3..ffd6a2795230 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -37,6 +37,64 @@ #include #include +/** + * DOC: getunique and setversion story + * + * BEWARE THE DRAGONS! MIND THE TRAPDOORS! + * + * In an attempt to warn anyone else who's trying to figure out what's going + * on here, I'll try to summarize the story. First things first, let's clear up + * the names, because the kernel internals, libdrm and the ioctls are all named + * differently: + * + * - GET_UNIQUE ioctl, implemented by drm_getunique is wrapped up in libdrm + * through the drmGetBusid function. + * - The libdrm drmSetBusid function is backed by the SET_UNIQUE ioctl. All + * that code is nerved in the kernel with drm_invalid_op(). + * - The internal set_busid kernel functions and driver callbacks are + * exclusively use by the SET_VERSION ioctl, because only drm 1.0 (which is + * nerved) allowed userspace to set the busid through the above ioctl. + * - Other ioctls and functions involved are named consistently. + * + * For anyone wondering what's the difference between drm 1.1 and 1.4: Correctly + * handling pci domains in the busid on ppc. Doing this correctly was only + * implemented in libdrm in 2010, hence can't be nerved yet. No one knows what's + * special with drm 1.2 and 1.3. + * + * Now the actual horror story of how device lookup in drm works. At large, + * there's 2 different ways, either by busid, or by device driver name. + * + * Opening by busid is fairly simple: + * + * 1. First call SET_VERSION to make sure pci domains are handled properly. As a + * side-effect this fills out the unique name in the master structure. + * 2. Call GET_UNIQUE to read out the unique name from the master structure, + * which matches the busid thanks to step 1. If it doesn't, proceed to try + * the next device node. + * + * Opening by name is slightly different: + * + * 1. Directly call VERSION to get the version and to match against the driver + * name returned by that ioctl. Note that SET_VERSION is not called, which + * means the the unique name for the master node just opening is _not_ filled + * out. This despite that with current drm device nodes are always bound to + * one device, and can't be runtime assigned like with drm 1.0. + * 2. Match driver name. If it mismatches, proceed to the next device node. + * 3. Call GET_UNIQUE, and check whether the unique name has length zero (by + * checking that the first byte in the string is 0). If that's not the case + * libdrm skips and proceeds to the next device node. Probably this is just + * copypasta from drm 1.0 times where a set unique name meant that the driver + * was in use already, but that's just conjecture. + * + * Long story short: To keep the open by name logic working, GET_UNIQUE must + * _not_ return a unique string when SET_VERSION hasn't been called yet, + * otherwise libdrm breaks. Even when that unique string can't ever change, and + * is totally irrelevant for actually opening the device because runtime + * assignable device instances were only support in drm 1.0, which is long dead. + * But the libdrm code in drmOpenByName somehow survived, hence this can't be + * broken. + */ + static int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 644169e1a029..2c819ef90090 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -68,24 +68,6 @@ err_free: return ret; } -int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master) -{ - int id; - - id = dev->platformdev->id; - if (id < 0) - id = 0; - - master->unique = kasprintf(GFP_KERNEL, "platform:%s:%02d", - dev->platformdev->name, id); - if (!master->unique) - return -ENOMEM; - - master->unique_len = strlen(master->unique); - return 0; -} -EXPORT_SYMBOL(drm_platform_set_busid); - /** * drm_platform_init - Register a platform device with the DRM subsystem * @driver: DRM device driver diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 3d4f56df8359..340d390306d8 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -496,7 +496,6 @@ static struct drm_driver etnaviv_drm_driver = { DRIVER_RENDER, .open = etnaviv_open, .preclose = etnaviv_preclose, - .set_busid = drm_platform_set_busid, .gem_free_object_unlocked = etnaviv_gem_free_object, .gem_vm_ops = &vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 4a679fb9bb02..13d28d4229e2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -407,7 +407,6 @@ static struct drm_driver exynos_drm_driver = { .preclose = exynos_drm_preclose, .lastclose = exynos_drm_lastclose, .postclose = exynos_drm_postclose, - .set_busid = drm_platform_set_busid, .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = exynos_drm_crtc_enable_vblank, .disable_vblank = exynos_drm_crtc_disable_vblank, diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index ef2c32ec1616..1edd9bc80294 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -171,7 +171,6 @@ static struct drm_driver kirin_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC | DRIVER_HAVE_IRQ, .fops = &kirin_drm_fops, - .set_busid = drm_platform_set_busid, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 82656654fb21..7746418a4c08 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -407,7 +407,6 @@ static struct drm_driver imx_drm_driver = { .load = imx_drm_driver_load, .unload = imx_drm_driver_unload, .lastclose = imx_drm_driver_lastclose, - .set_busid = drm_platform_set_busid, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = drm_gem_cma_dumb_create, diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 568fcc328f27..a02dc2b27739 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -722,7 +722,6 @@ static struct drm_driver msm_driver = { .open = msm_open, .preclose = msm_preclose, .lastclose = msm_lastclose, - .set_busid = drm_platform_set_busid, .irq_handler = msm_irq, .irq_preinstall = msm_irq_preinstall, .irq_postinstall = msm_irq_postinstall, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index c00ff6e786a3..295e7621cc68 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1070,7 +1070,6 @@ nouveau_drm_init(void) driver_pci = driver_stub; driver_pci.set_busid = drm_pci_set_busid; driver_platform = driver_stub; - driver_platform.set_busid = drm_platform_set_busid; nouveau_display_options(); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 6b97011154bf..26c6134eb744 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -801,7 +801,6 @@ static struct drm_driver omap_drm_driver = { .unload = dev_unload, .open = dev_open, .lastclose = dev_lastclose, - .set_busid = drm_platform_set_busid, .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = omap_irq_enable_vblank, .disable_vblank = omap_irq_disable_vblank, diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index ee79264b5b6a..f0492603ea88 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -259,7 +259,6 @@ static struct drm_driver shmob_drm_driver = { | DRIVER_PRIME, .load = shmob_drm_load, .unload = shmob_drm_unload, - .set_busid = drm_platform_set_busid, .irq_handler = shmob_drm_irq, .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = shmob_drm_enable_vblank, diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 308e197908fc..d27809372d54 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -541,7 +541,6 @@ static struct drm_driver tilcdc_driver = { .load = tilcdc_load, .unload = tilcdc_unload, .lastclose = tilcdc_lastclose, - .set_busid = drm_platform_set_busid, .irq_handler = tilcdc_irq, .irq_preinstall = tilcdc_irq_preinstall, .irq_postinstall = tilcdc_irq_postinstall, diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c index 88a39165edd5..7f0e93f87a55 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c @@ -27,16 +27,6 @@ #include "virtgpu_drv.h" -int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master) -{ - struct pci_dev *pdev = dev->pdev; - - if (pdev) { - return drm_pci_set_busid(dev, master); - } - return 0; -} - static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev) { struct apertures_struct *ap; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 5820b7020ae5..c13f70cfc461 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -117,7 +117,6 @@ static const struct file_operations virtio_gpu_driver_fops = { static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, - .set_busid = drm_virtio_set_busid, .load = virtio_gpu_driver_load, .unload = virtio_gpu_driver_unload, .open = virtio_gpu_driver_open, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index acf556a35cb2..b18ef3111f0c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -49,7 +49,6 @@ #define DRIVER_PATCHLEVEL 1 /* virtgpu_drm_bus.c */ -int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master); int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); struct virtio_gpu_object { diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fd4e4391aee5..babec2e80760 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1132,7 +1132,6 @@ extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw); /* platform section */ extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device); -extern int drm_platform_set_busid(struct drm_device *d, struct drm_master *m); /* returns true if currently okay to sleep */ static __inline__ bool drm_can_sleep(void) -- cgit v1.3-14-g43fede From 3b96a0b1407e08ebebe7a5c586752f7c16754cbd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 21 Jun 2016 10:54:22 +0200 Subject: drm: document drm_auth.c Also extract drm_auth.h for nicer grouping. v2: Nuke the other comments since they don't really explain a lot, and within the drm core we generally only document functions exported to drivers: The main audience for these docs are driver writers. v3: Limit the exposure of drm_master internals by only including drm_auth.h where it is neede (Chris). v4: Spelling polish (Emil). Cc: Chris Wilson Reviewed-by: Chris Wilson Reviewed-by: Emil Velikov Signed-off-by: Daniel Vetter --- Documentation/gpu/drm-uapi.rst | 13 +++++++ drivers/gpu/drm/drm_auth.c | 68 ++++++++++++++++++++++--------------- drivers/gpu/drm/drm_crtc.c | 1 + drivers/gpu/drm/drm_ioctl.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 + include/drm/drmP.h | 30 +--------------- include/drm/drm_auth.h | 59 ++++++++++++++++++++++++++++++++ include/drm/drm_legacy.h | 2 ++ 9 files changed, 119 insertions(+), 57 deletions(-) create mode 100644 include/drm/drm_auth.h (limited to 'Documentation') diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index a1c6f0103bc4..536bf3eaadd4 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -20,6 +20,19 @@ libdrm Device Lookup .. kernel-doc:: drivers/gpu/drm/drm_ioctl.c :doc: getunique and setversion story + +Primary Nodes, DRM Master and Authentication +============================================ + +.. kernel-doc:: drivers/gpu/drm/drm_auth.c + :doc: master and authentication + +.. kernel-doc:: drivers/gpu/drm/drm_auth.c + :export: + +.. kernel-doc:: include/drm/drm_auth.h + :internal: + Render nodes ============ diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 0a23b32e627c..4153e8a193af 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -33,17 +33,27 @@ #include "drm_legacy.h" /** - * drm_getmagic - Get unique magic of a client - * @dev: DRM device to operate on - * @data: ioctl data containing the drm_auth object - * @file_priv: DRM file that performs the operation + * DOC: master and authentication * - * This looks up the unique magic of the passed client and returns it. If the - * client did not have a magic assigned, yet, a new one is registered. The magic - * is stored in the passed drm_auth object. + * struct &drm_master is used to track groups of clients with open + * primary/legacy device nodes. For every struct &drm_file which has had at + * least once successfully became the device master (either through the + * SET_MASTER IOCTL, or implicitly through opening the primary device node when + * no one else is the current master that time) there exists one &drm_master. + * This is noted in the is_master member of &drm_file. All other clients have + * just a pointer to the &drm_master they are associated with. * - * Returns: 0 on success, negative error code on failure. + * In addition only one &drm_master can be the current master for a &drm_device. + * It can be switched through the DROP_MASTER and SET_MASTER IOCTL, or + * implicitly through closing/openeing the primary device node. See also + * drm_is_current_master(). + * + * Clients can authenticate against the current master (if it matches their own) + * using the GETMAGIC and AUTHMAGIC IOCTLs. Together with exchanging masters, + * this allows controlled access to the device for an entire group of mutually + * trusted clients. */ + int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_auth *auth = data; @@ -64,16 +74,6 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) return ret < 0 ? ret : 0; } -/** - * drm_authmagic - Authenticate client with a magic - * @dev: DRM device to operate on - * @data: ioctl data containing the drm_auth object - * @file_priv: DRM file that performs the operation - * - * This looks up a DRM client by the passed magic and authenticates it. - * - * Returns: 0 on success, negative error code on failure. - */ int drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -126,16 +126,6 @@ static int drm_set_master(struct drm_device *dev, struct drm_file *fpriv, return ret; } -/* - * drm_new_set_master - Allocate a new master object and become master for the - * associated master realm. - * - * @dev: The associated device. - * @fpriv: File private identifying the client. - * - * This function must be called with dev::master_mutex held. - * Returns negative error code on failure. Zero on success. - */ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) { struct drm_master *old_master; @@ -286,12 +276,28 @@ out: mutex_unlock(&dev->master_mutex); } +/** + * drm_is_current_master - checks whether @priv is the current master + * @fpriv: DRM file private + * + * Checks whether @fpriv is current master on its device. This decides whether a + * client is allowed to run DRM_MASTER IOCTLs. + * + * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting + * - the current master is assumed to own the non-shareable display hardware. + */ bool drm_is_current_master(struct drm_file *fpriv) { return fpriv->is_master && fpriv->master == fpriv->minor->dev->master; } EXPORT_SYMBOL(drm_is_current_master); +/** + * drm_master_get - reference a master pointer + * @master: struct &drm_master + * + * Increments the reference count of @master and returns a pointer to @master. + */ struct drm_master *drm_master_get(struct drm_master *master) { kref_get(&master->refcount); @@ -314,6 +320,12 @@ static void drm_master_destroy(struct kref *kref) kfree(master); } +/** + * drm_master_put - unreference and clear a master pointer + * @master: pointer to a pointer of struct &drm_master + * + * This decrements the &drm_master behind @master and sets it to NULL. + */ void drm_master_put(struct drm_master **master) { kref_put(&(*master)->refcount, drm_master_destroy); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e9cae0b7d7cd..fd93e9c79d28 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "drm_crtc_internal.h" #include "drm_internal.h" diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 827d221d69ce..1f84ff5f1bf8 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -30,6 +30,7 @@ #include #include +#include #include "drm_legacy.h" #include "drm_internal.h" #include "drm_crtc_internal.h" diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 285b107dea2d..ee338655f782 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -47,6 +47,7 @@ #include #include /* for struct drm_dma_handle */ #include +#include #include "i915_params.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1980e2a28265..9a90f824814e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/include/drm/drmP.h b/include/drm/drmP.h index bcde256987ec..cf918e3e6afb 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -86,6 +86,7 @@ struct drm_local_map; struct drm_device_dma; struct drm_dma_handle; struct drm_gem_object; +struct drm_master; struct device_node; struct videomode; @@ -373,30 +374,6 @@ struct drm_lock_data { int idle_has_lock; }; -/** - * struct drm_master - drm master structure - * - * @refcount: Refcount for this master object. - * @dev: Link back to the DRM device - * @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex. - * @unique_len: Length of unique field. Protected by drm_global_mutex. - * @magic_map: Map of used authentication tokens. Protected by struct_mutex. - * @lock: DRI lock information. - * @driver_priv: Pointer to driver-private information. - * - * Note that master structures are only relevant for the legacy/primary device - * nodes, hence there can only be one per device, not one per drm_minor. - */ -struct drm_master { - struct kref refcount; - struct drm_device *dev; - char *unique; - int unique_len; - struct idr magic_map; - struct drm_lock_data lock; - void *driver_priv; -}; - /* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 #define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) @@ -1012,11 +989,6 @@ static inline wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe); extern void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe); -/* drm_auth.c */ -struct drm_master *drm_master_get(struct drm_master *master); -void drm_master_put(struct drm_master **master); -bool drm_is_current_master(struct drm_file *fpriv); - /* drm_drv.c */ void drm_put_dev(struct drm_device *dev); void drm_unplug_dev(struct drm_device *dev); diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h new file mode 100644 index 000000000000..610223b0481b --- /dev/null +++ b/include/drm/drm_auth.h @@ -0,0 +1,59 @@ +/* + * Internal Header for the Direct Rendering Manager + * + * Copyright 2016 Intel Corporation + * + * Author: Daniel Vetter + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_AUTH_H_ +#define _DRM_AUTH_H_ + +/** + * struct drm_master - drm master structure + * + * @refcount: Refcount for this master object. + * @dev: Link back to the DRM device + * @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex. + * @unique_len: Length of unique field. Protected by drm_global_mutex. + * @magic_map: Map of used authentication tokens. Protected by struct_mutex. + * @lock: DRI lock information. + * @driver_priv: Pointer to driver-private information. + * + * Note that master structures are only relevant for the legacy/primary device + * nodes, hence there can only be one per device, not one per drm_minor. + */ +struct drm_master { + struct kref refcount; + struct drm_device *dev; + char *unique; + int unique_len; + struct idr magic_map; + struct drm_lock_data lock; + void *driver_priv; +}; + +struct drm_master *drm_master_get(struct drm_master *master); +void drm_master_put(struct drm_master **master); +bool drm_is_current_master(struct drm_file *fpriv); + +#endif diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h index a5ef2c7e40f8..cf0e7d89bcdf 100644 --- a/include/drm/drm_legacy.h +++ b/include/drm/drm_legacy.h @@ -1,6 +1,8 @@ #ifndef __DRM_DRM_LEGACY_H__ #define __DRM_DRM_LEGACY_H__ +#include + /* * Legacy driver interfaces for the Direct Rendering Manager * -- cgit v1.3-14-g43fede From 644a544fd9bcd65f524768b85ab22f62ed08e107 Mon Sep 17 00:00:00 2001 From: "Koehrer Mathias (ETAS/ESW5)" Date: Tue, 7 Jun 2016 14:24:17 +0000 Subject: PCI: Extending pci=resource_alignment to specify device/vendor IDs Some uio-based PCI drivers, e.g., uio_cif do not work if the assigned PCI memory resources are not page aligned. By using the kernel option "pci=resource_alignment" it is possible to force single PCI boards to use page alignment for their memory resources. However, this is fairly cumbersome if several of these boards are in use as the specification of the cards has to be done via PCI bus/slot/function number which might change, e.g., by adding another board. Extend the kernel option "pci=resource_alignment" to allow specification of relevant devices via PCI device/vendor (and subdevice/subvendor) IDs. The specification of the devices via device/vendor is indicated by a leading string "pci:" as argument to "pci=resource_alignment". The format of the specification is pci::[::] Signed-off-by: Mathias Koehrer Signed-off-by: Bjorn Helgaas --- Documentation/kernel-parameters.txt | 2 ++ drivers/pci/pci.c | 66 ++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 19 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..0618cdd5707e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2998,6 +2998,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. resource_alignment= Format: [@][:]:.[; ...] + [@]pci::\ + [::][; ...] Specifies alignment and device to reassign aligned memory resources. If is not specified, diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c8b4dbdd1bdd..78de36f1b012 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4755,6 +4755,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) { int seg, bus, slot, func, align_order, count; + unsigned short vendor, device, subsystem_vendor, subsystem_device; resource_size_t align = 0; char *p; @@ -4768,28 +4769,55 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) } else { align_order = -1; } - if (sscanf(p, "%x:%x:%x.%x%n", - &seg, &bus, &slot, &func, &count) != 4) { - seg = 0; - if (sscanf(p, "%x:%x.%x%n", - &bus, &slot, &func, &count) != 3) { - /* Invalid format */ - printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", - p); + if (strncmp(p, "pci:", 4) == 0) { + /* PCI vendor/device (subvendor/subdevice) ids are specified */ + p += 4; + if (sscanf(p, "%hx:%hx:%hx:%hx%n", + &vendor, &device, &subsystem_vendor, &subsystem_device, &count) != 4) { + if (sscanf(p, "%hx:%hx%n", &vendor, &device, &count) != 2) { + printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: pci:%s\n", + p); + break; + } + subsystem_vendor = subsystem_device = 0; + } + p += count; + if ((!vendor || (vendor == dev->vendor)) && + (!device || (device == dev->device)) && + (!subsystem_vendor || (subsystem_vendor == dev->subsystem_vendor)) && + (!subsystem_device || (subsystem_device == dev->subsystem_device))) { + if (align_order == -1) + align = PAGE_SIZE; + else + align = 1 << align_order; + /* Found */ break; } } - p += count; - if (seg == pci_domain_nr(dev->bus) && - bus == dev->bus->number && - slot == PCI_SLOT(dev->devfn) && - func == PCI_FUNC(dev->devfn)) { - if (align_order == -1) - align = PAGE_SIZE; - else - align = 1 << align_order; - /* Found */ - break; + else { + if (sscanf(p, "%x:%x:%x.%x%n", + &seg, &bus, &slot, &func, &count) != 4) { + seg = 0; + if (sscanf(p, "%x:%x.%x%n", + &bus, &slot, &func, &count) != 3) { + /* Invalid format */ + printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", + p); + break; + } + } + p += count; + if (seg == pci_domain_nr(dev->bus) && + bus == dev->bus->number && + slot == PCI_SLOT(dev->devfn) && + func == PCI_FUNC(dev->devfn)) { + if (align_order == -1) + align = PAGE_SIZE; + else + align = 1 << align_order; + /* Found */ + break; + } } if (*p != ';' && *p != ',') { /* End of param or invalid format */ -- cgit v1.3-14-g43fede From efe2938dd64cb990338a1f8a92e642f893e06c8d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 May 2015 14:32:59 -0300 Subject: [media] cec.txt: add CEC framework documentation Document the new HDMI CEC framework. [k.debski@samsung.com: add DocBook documentation by Hans Verkuil, with Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/cec.txt | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 Documentation/cec.txt (limited to 'Documentation') diff --git a/Documentation/cec.txt b/Documentation/cec.txt new file mode 100644 index 000000000000..75155fe37153 --- /dev/null +++ b/Documentation/cec.txt @@ -0,0 +1,267 @@ +CEC Kernel Support +================== + +The CEC framework provides a unified kernel interface for use with HDMI CEC +hardware. It is designed to handle a multiple types of hardware (receivers, +transmitters, USB dongles). The framework also gives the option to decide +what to do in the kernel driver and what should be handled by userspace +applications. In addition it integrates the remote control passthrough +feature into the kernel's remote control framework. + + +The CEC Protocol +---------------- + +The CEC protocol enables consumer electronic devices to communicate with each +other through the HDMI connection. The protocol uses logical addresses in the +communication. The logical address is strictly connected with the functionality +provided by the device. The TV acting as the communication hub is always +assigned address 0. The physical address is determined by the physical +connection between devices. + +The CEC framework described here is up to date with the CEC 2.0 specification. +It is documented in the HDMI 1.4 specification with the new 2.0 bits documented +in the HDMI 2.0 specification. But for most of the features the freely available +HDMI 1.3a specification is sufficient: + +http://www.microprocessor.org/HDMISpecification13a.pdf + + +The Kernel Interface +==================== + +CEC Adapter +----------- + +The struct cec_adapter represents the CEC adapter hardware. It is created by +calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): + +struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + void *priv, const char *name, u32 caps, u8 available_las, + struct device *parent); +void cec_delete_adapter(struct cec_adapter *adap); + +To create an adapter you need to pass the following information: + +ops: adapter operations which are called by the CEC framework and that you +have to implement. + +priv: will be stored in adap->priv and can be used by the adapter ops. + +name: the name of the CEC adapter. Note: this name will be copied. + +caps: capabilities of the CEC adapter. These capabilities determine the + capabilities of the hardware and which parts are to be handled + by userspace and which parts are handled by kernelspace. The + capabilities are returned by CEC_ADAP_G_CAPS. + +available_las: the number of simultaneous logical addresses that this + adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. + +parent: the parent device. + + +To register the /dev/cecX device node and the remote control device (if +CEC_CAP_RC is set) you call: + +int cec_register_adapter(struct cec_adapter *adap); + +To unregister the devices call: + +void cec_unregister_adapter(struct cec_adapter *adap); + +Note: if cec_register_adapter() fails, then call cec_delete_adapter() to +clean up. But if cec_register_adapter() succeeded, then only call +cec_unregister_adapter() to clean up, never cec_delete_adapter(). The +unregister function will delete the adapter automatically once the last user +of that /dev/cecX device has closed its file handle. + + +Implementing the Low-Level CEC Adapter +-------------------------------------- + +The following low-level adapter operations have to be implemented in +your driver: + +struct cec_adap_ops { + /* Low-level callbacks */ + int (*adap_enable)(struct cec_adapter *adap, bool enable); + int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); + int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); + int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg); + void (*adap_log_status)(struct cec_adapter *adap); + + /* High-level callbacks */ + ... +}; + +The three low-level ops deal with various aspects of controlling the CEC adapter +hardware: + + +To enable/disable the hardware: + + int (*adap_enable)(struct cec_adapter *adap, bool enable); + +This callback enables or disables the CEC hardware. Enabling the CEC hardware +means powering it up in a state where no logical addresses are claimed. This +op assumes that the physical address (adap->phys_addr) is valid when enable is +true and will not change while the CEC adapter remains enabled. The initial +state of the CEC adapter after calling cec_allocate_adapter() is disabled. + +Note that adap_enable must return 0 if enable is false. + + +To enable/disable the 'monitor all' mode: + + int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); + +If enabled, then the adapter should be put in a mode to also monitor messages +that not for us. Not all hardware supports this and this function is only +called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional +(some hardware may always be in 'monitor all' mode). + +Note that adap_monitor_all_enable must return 0 if enable is false. + + +To program a new logical address: + + int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); + +If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses +are to be erased. Otherwise the given logical address should be programmed. +If the maximum number of available logical addresses is exceeded, then it +should return -ENXIO. Once a logical address is programmed the CEC hardware +can receive directed messages to that address. + +Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID. + + +To transmit a new message: + + int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg); + +This transmits a new message. The attempts argument is the suggested number of +attempts for the transmit. + +The signal_free_time is the number of data bit periods that the adapter should +wait when the line is free before attempting to send a message. This value +depends on whether this transmit is a retry, a message from a new initiator or +a new message for the same initiator. Most hardware will handle this +automatically, but in some cases this information is needed. + +The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to +microseconds (one data bit period is 2.4 ms). + + +To log the current CEC hardware status: + + void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + +This optional callback can be used to show the status of the CEC hardware. +The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status + + +Your adapter driver will also have to react to events (typically interrupt +driven) by calling into the framework in the following situations: + +When a transmit finished (successfully or otherwise): + +void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, + u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); + +The status can be one of: + +CEC_TX_STATUS_OK: the transmit was successful. +CEC_TX_STATUS_ARB_LOST: arbitration was lost: another CEC initiator +took control of the CEC line and you lost the arbitration. +CEC_TX_STATUS_NACK: the message was nacked (for a directed message) or +acked (for a broadcast message). A retransmission is needed. +CEC_TX_STATUS_LOW_DRIVE: low drive was detected on the CEC bus. This +indicates that a follower detected an error on the bus and requested a +retransmission. +CEC_TX_STATUS_ERROR: some unspecified error occurred: this can be one of +the previous two if the hardware cannot differentiate or something else +entirely. +CEC_TX_STATUS_MAX_RETRIES: could not transmit the message after +trying multiple times. Should only be set by the driver if it has hardware +support for retrying messages. If set, then the framework assumes that it +doesn't have to make another attempt to transmit the message since the +hardware did that already. + +The *_cnt arguments are the number of error conditions that were seen. +This may be 0 if no information is available. Drivers that do not support +hardware retry can just set the counter corresponding to the transmit error +to 1, if the hardware does support retry then either set these counters to +0 if the hardware provides no feedback of which errors occurred and how many +times, or fill in the correct values as reported by the hardware. + +When a CEC message was received: + +void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); + +Speaks for itself. + +Implementing the High-Level CEC Adapter +--------------------------------------- + +The low-level operations drive the hardware, the high-level operations are +CEC protocol driven. The following high-level callbacks are available: + +struct cec_adap_ops { + /* Low-level callbacks */ + ... + + /* High-level CEC message callback */ + int (*received)(struct cec_adapter *adap, struct cec_msg *msg); +}; + +The received() callback allows the driver to optionally handle a newly +received CEC message + + int (*received)(struct cec_adapter *adap, struct cec_msg *msg); + +If the driver wants to process a CEC message, then it can implement this +callback. If it doesn't want to handle this message, then it should return +-ENOMSG, otherwise the CEC framework assumes it processed this message and +it will not no anything with it. + + +CEC framework functions +----------------------- + +CEC Adapter drivers can call the following CEC framework functions: + +int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, + bool block); + +Transmit a CEC message. If block is true, then wait until the message has been +transmitted, otherwise just queue it and return. + +void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block); + +Change the physical address. This function will set adap->phys_addr and +send an event if it has changed. If cec_s_log_addrs() has been called and +the physical address has become valid, then the CEC framework will start +claiming the logical addresses. If block is true, then this function won't +return until this process has finished. + +When the physical address is set to a valid value the CEC adapter will +be enabled (see the adap_enable op). When it is set to CEC_PHYS_ADDR_INVALID, +then the CEC adapter will be disabled. If you change a valid physical address +to another valid physical address, then this function will first set the +address to CEC_PHYS_ADDR_INVALID before enabling the new physical address. + +int cec_s_log_addrs(struct cec_adapter *adap, + struct cec_log_addrs *log_addrs, bool block); + +Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS +is set. If block is true, then wait until the logical addresses have been +claimed, otherwise just queue it and return. To unconfigure all logical +addresses call this function with log_addrs set to NULL or with +log_addrs->num_log_addrs set to 0. The block argument is ignored when +unconfiguring. This function will just return if the physical address is +invalid. Once the physical address becomes valid, then the framework will +attempt to claim these logical addresses. -- cgit v1.3-14-g43fede From a777059a3fc13f51e91442ccf043c8e3bcd1c48f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Jun 2016 14:48:26 +0200 Subject: spi: Improve DT binding documentation - Add missing verbs and periods, - Add spaces before opening parentheses, - Align list layout, - Correct grammar, - Move "cs-gpios" from the required to the optional properties section, - Remove spaces before tabs. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-bus.txt | 35 ++++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index 42d595425dfb..17822860cb98 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt @@ -8,11 +8,10 @@ in slave mode. The SPI master node requires the following properties: - #address-cells - number of cells required to define a chip select - address on the SPI bus. + address on the SPI bus. - #size-cells - should be zero. - compatible - name of SPI bus controller following generic names - recommended practice. -- cs-gpios - (optional) gpios chip select. + recommended practice. No other properties are required in the SPI bus node. It is assumed that a driver for an SPI bus device will understand that it is an SPI bus. However, the binding does not attempt to define the specific method for @@ -22,11 +21,12 @@ assumption that board specific platform code will be used to manage chip selects. Individual drivers can define additional properties to support describing the chip select layout. -Optional property: -- num-cs : total number of chipselects +Optional properties: +- cs-gpios - gpios chip select. +- num-cs - total number of chipselects. -If cs-gpios is used the number of chip select will automatically increased -with max(cs-gpios > hw cs) +If cs-gpios is used the number of chip selects will be increased automatically +with max(cs-gpios > hw cs). So if for example the controller has 2 CS lines, and the cs-gpios property looks like this: @@ -45,29 +45,30 @@ SPI slave nodes must be children of the SPI master node and can contain the following properties. - reg - (required) chip select address of device. - compatible - (required) name of SPI device following generic names - recommended practice -- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz + recommended practice. +- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz. - spi-cpol - (optional) Empty property indicating device requires - inverse clock polarity (CPOL) mode + inverse clock polarity (CPOL) mode. - spi-cpha - (optional) Empty property indicating device requires - shifted clock phase (CPHA) mode + shifted clock phase (CPHA) mode. - spi-cs-high - (optional) Empty property indicating device requires - chip select active high + chip select active high. - spi-3wire - (optional) Empty property indicating device requires - 3-wire mode. + 3-wire mode. - spi-lsb-first - (optional) Empty property indicating device requires LSB first mode. -- spi-tx-bus-width - (optional) The bus width(number of data wires) that +- spi-tx-bus-width - (optional) The bus width (number of data wires) that is used for MOSI. Defaults to 1 if not present. -- spi-rx-bus-width - (optional) The bus width(number of data wires) that +- spi-rx-bus-width - (optional) The bus width (number of data wires) that is used for MISO. Defaults to 1 if not present. - spi-rx-delay-us - (optional) Microsecond delay after a read transfer. - spi-tx-delay-us - (optional) Microsecond delay after a write transfer. Some SPI controllers and devices support Dual and Quad SPI transfer mode. -It allows data in the SPI system to be transferred in 2 wires(DUAL) or 4 wires(QUAD). +It allows data in the SPI system to be transferred using 2 wires (DUAL) or 4 +wires (QUAD). Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is -only 1(SINGLE), 2(DUAL) and 4(QUAD). +only 1 (SINGLE), 2 (DUAL) and 4 (QUAD). Dual/Quad mode is not allowed when 3-wire mode is used. If a gpio chipselect is used for the SPI slave the gpio number will be passed -- cgit v1.3-14-g43fede From c9506bb84b62917ae88087545ccb756d35655397 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 17 Jun 2016 11:02:24 +0800 Subject: ASoC: rt5514: Add the MCLK handling The patch adds the control of MCLK that depends on the status of DAPM. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rt5514.txt | 5 ++++ sound/soc/codecs/rt5514.c | 32 ++++++++++++++++++++++ sound/soc/codecs/rt5514.h | 3 ++ 3 files changed, 40 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/rt5514.txt b/Documentation/devicetree/bindings/sound/rt5514.txt index e24436fc5ea9..9cabfc18cb57 100644 --- a/Documentation/devicetree/bindings/sound/rt5514.txt +++ b/Documentation/devicetree/bindings/sound/rt5514.txt @@ -8,6 +8,11 @@ Required properties: - reg : The I2C address of the device. +Optional properties: + +- clocks: The phandle of the master clock to the CODEC +- clock-names: Should be "mclk" + Pins on the device (for linking into audio routes) for RT5514: * DMIC1L diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 879bf60f4965..e6ae2309e5f8 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -799,10 +799,41 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, return 0; } +static int rt5514_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); + int ret; + + switch (level) { + case SND_SOC_BIAS_PREPARE: + if (IS_ERR(rt5514->mclk)) + break; + + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) { + clk_disable_unprepare(rt5514->mclk); + } else { + ret = clk_prepare_enable(rt5514->mclk); + if (ret) + return ret; + } + break; + + default: + break; + } + + return 0; +} + static int rt5514_probe(struct snd_soc_codec *codec) { struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); + rt5514->mclk = devm_clk_get(codec->dev, "mclk"); + if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + rt5514->codec = codec; return 0; @@ -858,6 +889,7 @@ struct snd_soc_dai_driver rt5514_dai[] = { static struct snd_soc_codec_driver soc_codec_dev_rt5514 = { .probe = rt5514_probe, .idle_bias_off = true, + .set_bias_level = rt5514_set_bias_level, .controls = rt5514_snd_controls, .num_controls = ARRAY_SIZE(rt5514_snd_controls), .dapm_widgets = rt5514_dapm_widgets, diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h index 6ad8a612f659..766f5a666ebe 100644 --- a/sound/soc/codecs/rt5514.h +++ b/sound/soc/codecs/rt5514.h @@ -12,6 +12,8 @@ #ifndef __RT5514_H__ #define __RT5514_H__ +#include + #define RT5514_DEVICE_ID 0x10ec5514 #define RT5514_RESET 0x2000 @@ -240,6 +242,7 @@ enum { struct rt5514_priv { struct snd_soc_codec *codec; struct regmap *i2c_regmap, *regmap; + struct clk *mclk; int sysclk; int sysclk_src; int lrck; -- cgit v1.3-14-g43fede From 50ad77db41fe3a08aeeae04088869142a1d9d007 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Fri, 13 May 2016 00:13:12 +0930 Subject: doc/devicetree: Add Aspeed VIC bindings Signed-off-by: Joel Stanley Link: https://lkml.kernel.org/r/1463064193-2178-2-git-send-email-joel@jms.id.au Signed-off-by: Jason Cooper --- .../interrupt-controller/aspeed,ast2400-vic.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-vic.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-vic.txt b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-vic.txt new file mode 100644 index 000000000000..6c6e85324b9d --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-vic.txt @@ -0,0 +1,22 @@ +Aspeed Vectored Interrupt Controller + +These bindings are for the Aspeed AST2400 interrupt controller register layout. +The SoC has an legacy register layout, but this driver does not support that +mode of operation. + +Required properties: + +- compatible : should be "aspeed,ast2400-vic". + +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 1. + +Example: + + vic: interrupt-controller@1e6c0080 { + compatible = "aspeed,ast2400-vic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x1e6c0080 0x80>; + }; -- cgit v1.3-14-g43fede From 2cc9e7ec219819db10474160d65837c6c260522a Mon Sep 17 00:00:00 2001 From: Michael Turquette Date: Thu, 9 Jun 2016 16:20:47 -0700 Subject: clk: gxbb: Document bindings for the GXBB clock controller Add documentations for the clock controller. Tested-by: Kevin Hilman Signed-off-by: Michael Turquette --- .../bindings/clock/amlogic,gxbb-clkc.txt | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt new file mode 100644 index 000000000000..ce06435d28ed --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt @@ -0,0 +1,36 @@ +* Amlogic GXBB Clock and Reset Unit + +The Amlogic GXBB clock controller generates and supplies clock to various +controllers within the SoC. + +Required Properties: + +- compatible: should be "amlogic,gxbb-clkc" +- reg: physical base address of the clock controller and length of memory + mapped region. + +- #clock-cells: should be 1. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/gxbb-clkc.h header and can be +used in device tree sources. + +Example: Clock controller node: + + clkc: clock-controller@c883c000 { + #clock-cells = <1>; + compatible = "amlogic,gxbb-clkc"; + reg = <0x0 0xc883c000 0x0 0x3db>; + }; + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart_AO: serial@c81004c0 { + compatible = "amlogic,meson-uart"; + reg = <0xc81004c0 0x14>; + interrupts = <0 90 1>; + clocks = <&clkc CLKID_CLK81>; + status = "disabled"; + }; -- cgit v1.3-14-g43fede From 7440926ed9623dceca3310c5f437d06c859dc02b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 21 Jun 2016 01:40:48 +0300 Subject: pinctrl: Flag strict is a field in struct pinmux_ops Documentation incorrectly refers to struct pinctrl_desc, where no such flag is available. Replace the name of the struct. Fixes: commit 8c4c2016345f ("pinctrl: move strict option to pinmux_ops") Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 6414a613cb8a..0d3b9ce0a0b9 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -831,7 +831,7 @@ separate memory range only intended for GPIO driving, and the register range dealing with pin config and pin multiplexing get placed into a different memory range and a separate section of the data sheet. -A flag "strict" in struct pinctrl_desc is available to check and deny +A flag "strict" in struct pinmux_ops is available to check and deny simultaneous access to the same pin from GPIO and pin multiplexing consumers on hardware of this type. The pinctrl driver should set this flag accordingly. -- cgit v1.3-14-g43fede From 6f4c2eea353809fb85386d5ce17a30e37042847d Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Wed, 22 Jun 2016 13:31:46 +0100 Subject: can: rcar_canfd: Add Classical CAN only mode support The controller can operate in one of the two global modes - CAN FD only mode (default) - Classical CAN (CAN2.0) only mode This patch adds support for Classical CAN only mode. It can be enabled by defining the optional device tree property "renesas,no-can-fd" of this node. Note: R-Car Gen3 h/w manual v0.51E shows bit6 of RSCFDnCFDGCFG as reserved, which is incorrect. This bit is same as RSCFDnGCFG. Signed-off-by: Ramesh Shanmugasundaram Signed-off-by: Marc Kleine-Budde --- .../devicetree/bindings/net/can/rcar_canfd.txt | 21 +- drivers/net/can/rcar/rcar_canfd.c | 355 ++++++++++++++------- 2 files changed, 255 insertions(+), 121 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt index d45182bd21dd..22a6f10bab05 100644 --- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt +++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt @@ -32,6 +32,12 @@ below properties. - assigned-clocks: phandle of canfd clock. - assigned-clock-rates: maximum frequency of this clock. +Optional property: +The controller can operate in either CAN FD only mode (default) or +Classical CAN only mode. The mode is global to both the channels. In order to +enable the later, define the following optional property. + - renesas,no-can-fd: puts the controller in Classical CAN only mode. + Example ------- @@ -63,12 +69,13 @@ SoC common .dtsi file: Board specific .dts file: -E.g. below enables Channel 1 alone in the board. +E.g. below enables Channel 1 alone in the board in Classical CAN only mode. &canfd { - pinctrl-0 = <&canfd1_pins>; - pinctrl-names = "default"; - status = "okay"; + pinctrl-0 = <&canfd1_pins>; + pinctrl-names = "default"; + renesas,no-can-fd; + status = "okay"; channel1 { status = "okay"; @@ -79,9 +86,9 @@ E.g. below enables Channel 0 alone in the board using External clock as fCAN clock. &canfd { - pinctrl-0 = <&canfd0_pins &can_clk_pins>; - pinctrl-names = "default"; - status = "okay"; + pinctrl-0 = <&canfd0_pins &can_clk_pins>; + pinctrl-names = "default"; + status = "okay"; channel0 { status = "okay"; diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index a39d9224166c..6bcc47408423 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -16,8 +16,9 @@ * mode, the controller acts as a CAN FD node that can also interoperate with * CAN 2.0 nodes. * - * As of now, this driver does not support the Classical CAN (CAN 2.0) mode, - * which is handled by a different register map compared to CAN FD only mode. + * To switch the controller to Classical CAN (CAN 2.0) only mode, add + * "renesas,no-can-fd" optional property to the device tree node. A h/w reset is + * also required to switch modes. * * Note: The h/w manual register naming convention is clumsy and not acceptable * to use as it is in the driver. However, those names are added as comments @@ -48,15 +49,16 @@ /* RSCFDnCFDGRMCFG */ #define RCANFD_GRMCFG_RCMC BIT(0) -/* RSCFDnCFDGCFG */ -#define RCANFD_GCFG_CMPOC BIT(5) +/* RSCFDnCFDGCFG / RSCFDnGCFG */ +#define RCANFD_GCFG_EEFE BIT(6) +#define RCANFD_GCFG_CMPOC BIT(5) /* CAN FD only */ #define RCANFD_GCFG_DCS BIT(4) #define RCANFD_GCFG_DCE BIT(1) #define RCANFD_GCFG_TPRI BIT(0) -/* RSCFDnCFDGCTR */ +/* RSCFDnCFDGCTR / RSCFDnGCTR */ #define RCANFD_GCTR_TSRST BIT(16) -#define RCANFD_GCTR_CFMPOFIE BIT(11) +#define RCANFD_GCTR_CFMPOFIE BIT(11) /* CAN FD only */ #define RCANFD_GCTR_THLEIE BIT(10) #define RCANFD_GCTR_MEIE BIT(9) #define RCANFD_GCTR_DEIE BIT(8) @@ -66,7 +68,7 @@ #define RCANFD_GCTR_GMDC_GRESET (0x1) #define RCANFD_GCTR_GMDC_GTEST (0x2) -/* RSCFDnCFDGSTS */ +/* RSCFDnCFDGSTS / RSCFDnGSTS */ #define RCANFD_GSTS_GRAMINIT BIT(3) #define RCANFD_GSTS_GSLPSTS BIT(2) #define RCANFD_GSTS_GHLTSTS BIT(1) @@ -74,44 +76,50 @@ /* Non-operational status */ #define RCANFD_GSTS_GNOPM (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -/* RSCFDnCFDGERFL */ +/* RSCFDnCFDGERFL / RSCFDnGERFL */ #define RCANFD_GERFL_EEF1 BIT(17) #define RCANFD_GERFL_EEF0 BIT(16) -#define RCANFD_GERFL_CMPOF BIT(3) +#define RCANFD_GERFL_CMPOF BIT(3) /* CAN FD only */ #define RCANFD_GERFL_THLES BIT(2) #define RCANFD_GERFL_MES BIT(1) #define RCANFD_GERFL_DEF BIT(0) -#define RCANFD_GERFL_ERR(x) ((x) & (RCANFD_GERFL_EEF1 |\ - RCANFD_GERFL_EEF0 |\ - RCANFD_GERFL_MES |\ - RCANFD_GERFL_CMPOF)) +#define RCANFD_GERFL_ERR(gpriv, x) ((x) & (RCANFD_GERFL_EEF1 |\ + RCANFD_GERFL_EEF0 | RCANFD_GERFL_MES |\ + (gpriv->fdmode ?\ + RCANFD_GERFL_CMPOF : 0))) /* AFL Rx rules registers */ -/* RSCFDnCFDGAFLCFG0 */ +/* RSCFDnCFDGAFLCFG0 / RSCFDnGAFLCFG0 */ #define RCANFD_GAFLCFG_SETRNC(n, x) (((x) & 0xff) << (24 - n * 8)) #define RCANFD_GAFLCFG_GETRNC(n, x) (((x) >> (24 - n * 8)) & 0xff) -/* RSCFDnCFDGAFLECTR */ +/* RSCFDnCFDGAFLECTR / RSCFDnGAFLECTR */ #define RCANFD_GAFLECTR_AFLDAE BIT(8) #define RCANFD_GAFLECTR_AFLPN(x) ((x) & 0x1f) -/* RSCFDnCFDGAFLIDj */ +/* RSCFDnCFDGAFLIDj / RSCFDnGAFLIDj */ #define RCANFD_GAFLID_GAFLLB BIT(29) -/* RSCFDnCFDGAFLP1_j */ +/* RSCFDnCFDGAFLP1_j / RSCFDnGAFLP1_j */ #define RCANFD_GAFLP1_GAFLFDP(x) (1 << (x)) /* Channel register bits */ -/* RSCFDnCFDCmNCFG */ +/* RSCFDnCmCFG - Classical CAN only */ +#define RCANFD_CFG_SJW(x) (((x) & 0x3) << 24) +#define RCANFD_CFG_TSEG2(x) (((x) & 0x7) << 20) +#define RCANFD_CFG_TSEG1(x) (((x) & 0xf) << 16) +#define RCANFD_CFG_BRP(x) (((x) & 0x3ff) << 0) + +/* RSCFDnCFDCmNCFG - CAN FD only */ #define RCANFD_NCFG_NTSEG2(x) (((x) & 0x1f) << 24) #define RCANFD_NCFG_NTSEG1(x) (((x) & 0x7f) << 16) #define RCANFD_NCFG_NSJW(x) (((x) & 0x1f) << 11) #define RCANFD_NCFG_NBRP(x) (((x) & 0x3ff) << 0) -/* RSCFDnCFDCmCTR */ +/* RSCFDnCFDCmCTR / RSCFDnCmCTR */ #define RCANFD_CCTR_CTME BIT(24) #define RCANFD_CCTR_ERRD BIT(23) #define RCANFD_CCTR_BOM_MASK (0x3 << 21) @@ -136,7 +144,7 @@ #define RCANFD_CCTR_CHDMC_CRESET (0x1) #define RCANFD_CCTR_CHDMC_CHLT (0x2) -/* RSCFDnCFDCmSTS */ +/* RSCFDnCFDCmSTS / RSCFDnCmSTS */ #define RCANFD_CSTS_COMSTS BIT(7) #define RCANFD_CSTS_RECSTS BIT(6) #define RCANFD_CSTS_TRMSTS BIT(5) @@ -149,7 +157,7 @@ #define RCANFD_CSTS_TECCNT(x) (((x) >> 24) & 0xff) #define RCANFD_CSTS_RECCNT(x) (((x) >> 16) & 0xff) -/* RSCFDnCFDCmERFL */ +/* RSCFDnCFDCmERFL / RSCFDnCmERFL */ #define RCANFD_CERFL_ADERR BIT(14) #define RCANFD_CERFL_B0ERR BIT(13) #define RCANFD_CERFL_B1ERR BIT(12) @@ -239,14 +247,14 @@ #define RCANFD_CFFDCSTS_CFBRS BIT(1) #define RCANFD_CFFDCSTS_CFESI BIT(0) -/* This controller supports classical CAN only mode or CAN FD only mode. These - * modes are supported in two separate set of register maps & names. However, - * some of the register offsets are common for both modes. Those offsets are - * listed below as Common registers. +/* This controller supports either Classical CAN only mode or CAN FD only mode. + * These modes are supported in two separate set of register maps & names. + * However, some of the register offsets are common for both modes. Those + * offsets are listed below as Common registers. * - * The CAN FD only specific registers are listed separately and their names - * starts with RCANFD_F_xxx names. When classical CAN only specific registers - * are added, those specific registers can be prefixed as RCANFD_C_xxx. + * The CAN FD only mode specific registers & Classical CAN only mode specific + * registers are listed separately. Their register names starts with + * RCANFD_F_xxx & RCANFD_C_xxx respectively. */ /* Common registers */ @@ -353,7 +361,7 @@ #define RCANFD_GTSTCTR (0x046c) /* RSCFDnCFDGLOCKK / RSCFDnGLOCKK */ #define RCANFD_GLOCKK (0x047c) -/* RSCFDnCFDGRMCFG / RSCFDnGRMCFG */ +/* RSCFDnCFDGRMCFG */ #define RCANFD_GRMCFG (0x04fc) /* RSCFDnCFDGAFLIDj / RSCFDnGAFLIDj */ @@ -365,6 +373,46 @@ /* RSCFDnCFDGAFLP1j / RSCFDnGAFLP1j */ #define RCANFD_GAFLP1(offset, j) ((offset) + 0x0c + (0x10 * (j))) +/* Classical CAN only mode register map */ + +/* RSCFDnGAFLXXXj offset */ +#define RCANFD_C_GAFL_OFFSET (0x0500) + +/* RSCFDnRMXXXq -> RCANFD_C_RMXXX(q) */ +#define RCANFD_C_RMID(q) (0x0600 + (0x10 * (q))) +#define RCANFD_C_RMPTR(q) (0x0604 + (0x10 * (q))) +#define RCANFD_C_RMDF0(q) (0x0608 + (0x10 * (q))) +#define RCANFD_C_RMDF1(q) (0x060c + (0x10 * (q))) + +/* RSCFDnRFXXx -> RCANFD_C_RFXX(x) */ +#define RCANFD_C_RFOFFSET (0x0e00) +#define RCANFD_C_RFID(x) (RCANFD_C_RFOFFSET + (0x10 * (x))) +#define RCANFD_C_RFPTR(x) (RCANFD_C_RFOFFSET + 0x04 + \ + (0x10 * (x))) +#define RCANFD_C_RFDF(x, df) (RCANFD_C_RFOFFSET + 0x08 + \ + (0x10 * (x)) + (0x04 * (df))) + +/* RSCFDnCFXXk -> RCANFD_C_CFXX(ch, k) */ +#define RCANFD_C_CFOFFSET (0x0e80) +#define RCANFD_C_CFID(ch, idx) (RCANFD_C_CFOFFSET + (0x30 * (ch)) + \ + (0x10 * (idx))) +#define RCANFD_C_CFPTR(ch, idx) (RCANFD_C_CFOFFSET + 0x04 + \ + (0x30 * (ch)) + (0x10 * (idx))) +#define RCANFD_C_CFDF(ch, idx, df) (RCANFD_C_CFOFFSET + 0x08 + \ + (0x30 * (ch)) + (0x10 * (idx)) + \ + (0x04 * (df))) + +/* RSCFDnTMXXp -> RCANFD_C_TMXX(p) */ +#define RCANFD_C_TMID(p) (0x1000 + (0x10 * (p))) +#define RCANFD_C_TMPTR(p) (0x1004 + (0x10 * (p))) +#define RCANFD_C_TMDF0(p) (0x1008 + (0x10 * (p))) +#define RCANFD_C_TMDF1(p) (0x100c + (0x10 * (p))) + +/* RSCFDnTHLACCm */ +#define RCANFD_C_THLACC(m) (0x1800 + (0x04 * (m))) +/* RSCFDnRPGACCr */ +#define RCANFD_C_RPGACC(r) (0x1900 + (0x04 * (r))) + /* CAN FD mode specific regsiter map */ /* RSCFDnCFDCmXXX -> RCANFD_F_XXX(m) */ @@ -468,6 +516,7 @@ struct rcar_canfd_global { struct clk *can_clk; /* fCAN clock */ enum rcar_canfd_fcanclk fcan; /* CANFD or Ext clock */ unsigned long channels_mask; /* Enabled channels mask */ + bool fdmode; /* CAN FD or Classical CAN only mode */ }; /* CAN FD mode nominal rate constants */ @@ -496,6 +545,19 @@ static const struct can_bittiming_const rcar_canfd_data_bittiming_const = { .brp_inc = 1, }; +/* Classical CAN mode bitrate constants */ +static const struct can_bittiming_const rcar_canfd_bittiming_const = { + .name = RCANFD_DRV_NAME, + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + /* Helper functions */ static inline void rcar_canfd_update(u32 mask, u32 val, u32 __iomem *reg) { @@ -593,8 +655,13 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) /* Reset Global error flags */ rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0); - /* Set the controller into FD mode */ - rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, RCANFD_GRMCFG_RCMC); + /* Set the controller into appropriate mode */ + if (gpriv->fdmode) + rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, + RCANFD_GRMCFG_RCMC); + else + rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG, + RCANFD_GRMCFG_RCMC); /* Transition all Channels to reset mode */ for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) { @@ -624,8 +691,12 @@ static void rcar_canfd_configure_controller(struct rcar_canfd_global *gpriv) /* Global configuration settings */ - /* Truncate payload to configured message size RFPLS */ - cfg = RCANFD_GCFG_CMPOC; + /* ECC Error flag Enable */ + cfg = RCANFD_GCFG_EEFE; + + if (gpriv->fdmode) + /* Truncate payload to configured message size RFPLS */ + cfg |= RCANFD_GCFG_CMPOC; /* Set External Clock if selected */ if (gpriv->fcan != RCANFD_CANFDCLK) @@ -647,7 +718,7 @@ static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv, u32 ch) { u32 cfg; - int start, page, num_rules = RCANFD_CHANNEL_NUMRULES; + int offset, start, page, num_rules = RCANFD_CHANNEL_NUMRULES; u32 ridx = ch + RCANFD_RFFIFO_IDX; if (ch == 0) { @@ -667,19 +738,19 @@ static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv, /* Write number of rules for channel */ rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLCFG0, RCANFD_GAFLCFG_SETRNC(ch, num_rules)); + if (gpriv->fdmode) + offset = RCANFD_F_GAFL_OFFSET; + else + offset = RCANFD_C_GAFL_OFFSET; /* Accept all IDs */ - rcar_canfd_write(gpriv->base, - RCANFD_GAFLID(RCANFD_F_GAFL_OFFSET, start), 0); + rcar_canfd_write(gpriv->base, RCANFD_GAFLID(offset, start), 0); /* IDE or RTR is not considered for matching */ - rcar_canfd_write(gpriv->base, - RCANFD_GAFLM(RCANFD_F_GAFL_OFFSET, start), 0); + rcar_canfd_write(gpriv->base, RCANFD_GAFLM(offset, start), 0); /* Any data length accepted */ - rcar_canfd_write(gpriv->base, - RCANFD_GAFLP0(RCANFD_F_GAFL_OFFSET, start), 0); + rcar_canfd_write(gpriv->base, RCANFD_GAFLP0(offset, start), 0); /* Place the msg in corresponding Rx FIFO entry */ - rcar_canfd_write(gpriv->base, - RCANFD_GAFLP1(RCANFD_F_GAFL_OFFSET, start), + rcar_canfd_write(gpriv->base, RCANFD_GAFLP1(offset, start), RCANFD_GAFLP1_GAFLFDP(ridx)); /* Disable write access to page */ @@ -697,7 +768,10 @@ static void rcar_canfd_configure_rx(struct rcar_canfd_global *gpriv, u32 ch) u32 ridx = ch + RCANFD_RFFIFO_IDX; rfdc = 2; /* b010 - 8 messages Rx FIFO depth */ - rfpls = 7; /* b111 - Max 64 bytes payload */ + if (gpriv->fdmode) + rfpls = 7; /* b111 - Max 64 bytes payload */ + else + rfpls = 0; /* b000 - Max 8 bytes payload */ cfg = (RCANFD_RFCC_RFIM | RCANFD_RFCC_RFDC(rfdc) | RCANFD_RFCC_RFPLS(rfpls) | RCANFD_RFCC_RFIE); @@ -718,16 +792,20 @@ static void rcar_canfd_configure_tx(struct rcar_canfd_global *gpriv, u32 ch) cftml = 0; /* 0th buffer */ cfm = 1; /* b01 - Transmit mode */ cfdc = 2; /* b010 - 8 messages Tx FIFO depth */ - cfpls = 7; /* b111 - Max 64 bytes payload */ + if (gpriv->fdmode) + cfpls = 7; /* b111 - Max 64 bytes payload */ + else + cfpls = 0; /* b000 - Max 8 bytes payload */ cfg = (RCANFD_CFCC_CFTML(cftml) | RCANFD_CFCC_CFM(cfm) | RCANFD_CFCC_CFIM | RCANFD_CFCC_CFDC(cfdc) | RCANFD_CFCC_CFPLS(cfpls) | RCANFD_CFCC_CFTXIE); rcar_canfd_write(gpriv->base, RCANFD_CFCC(ch, RCANFD_CFFIFO_IDX), cfg); - /* Clear FD mode specific control/status register */ - rcar_canfd_write(gpriv->base, - RCANFD_F_CFFDCSTS(ch, RCANFD_CFFIFO_IDX), 0); + if (gpriv->fdmode) + /* Clear FD mode specific control/status register */ + rcar_canfd_write(gpriv->base, + RCANFD_F_CFFDCSTS(ch, RCANFD_CFFIFO_IDX), 0); } static void rcar_canfd_enable_global_interrupts(struct rcar_canfd_global *gpriv) @@ -739,7 +817,8 @@ static void rcar_canfd_enable_global_interrupts(struct rcar_canfd_global *gpriv) /* Global interrupts setup */ ctr = RCANFD_GCTR_MEIE; - ctr |= RCANFD_GCTR_CFMPOFIE; + if (gpriv->fdmode) + ctr |= RCANFD_GCTR_CFMPOFIE; rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, ctr); } @@ -790,6 +869,7 @@ static void rcar_canfd_disable_channel_interrupts(struct rcar_canfd_channel static void rcar_canfd_global_error(struct net_device *ndev) { struct rcar_canfd_channel *priv = netdev_priv(ndev); + struct rcar_canfd_global *gpriv = priv->gpriv; struct net_device_stats *stats = &ndev->stats; u32 ch = priv->channel; u32 gerfl, sts; @@ -823,7 +903,7 @@ static void rcar_canfd_global_error(struct net_device *ndev) sts & ~RCANFD_RFSTS_RFMLT); } } - if (gerfl & RCANFD_GERFL_CMPOF) { + if (gpriv->fdmode && gerfl & RCANFD_GERFL_CMPOF) { /* Message Lost flag will be set for respective channel * when this condition happens with counters and flags * already updated. @@ -1018,7 +1098,7 @@ static irqreturn_t rcar_canfd_global_interrupt(int irq, void *dev_id) /* Global error interrupts */ gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL); - if (RCANFD_GERFL_ERR(gerfl)) + if (RCANFD_GERFL_ERR(gpriv, gerfl)) rcar_canfd_global_error(ndev); /* Handle Rx interrupts */ @@ -1077,25 +1157,37 @@ static void rcar_canfd_set_bittiming(struct net_device *dev) tseg1 = bt->prop_seg + bt->phase_seg1 - 1; tseg2 = bt->phase_seg2 - 1; - cfg = (RCANFD_NCFG_NTSEG1(tseg1) | RCANFD_NCFG_NBRP(brp) | - RCANFD_NCFG_NSJW(sjw) | RCANFD_NCFG_NTSEG2(tseg2)); + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + /* CAN FD only mode */ + cfg = (RCANFD_NCFG_NTSEG1(tseg1) | RCANFD_NCFG_NBRP(brp) | + RCANFD_NCFG_NSJW(sjw) | RCANFD_NCFG_NTSEG2(tseg2)); - rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg); - netdev_dbg(priv->ndev, "nrate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", - brp, sjw, tseg1, tseg2); + rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg); + netdev_dbg(priv->ndev, "nrate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", + brp, sjw, tseg1, tseg2); - /* Data bit timing settings */ - brp = dbt->brp - 1; - sjw = dbt->sjw - 1; - tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; - tseg2 = dbt->phase_seg2 - 1; + /* Data bit timing settings */ + brp = dbt->brp - 1; + sjw = dbt->sjw - 1; + tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; + tseg2 = dbt->phase_seg2 - 1; - cfg = (RCANFD_DCFG_DTSEG1(tseg1) | RCANFD_DCFG_DBRP(brp) | - RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(tseg2)); + cfg = (RCANFD_DCFG_DTSEG1(tseg1) | RCANFD_DCFG_DBRP(brp) | + RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(tseg2)); - rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg); - netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", - brp, sjw, tseg1, tseg2); + rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg); + netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", + brp, sjw, tseg1, tseg2); + } else { + /* Classical CAN only mode */ + cfg = (RCANFD_CFG_TSEG1(tseg1) | RCANFD_CFG_BRP(brp) | + RCANFD_CFG_SJW(sjw) | RCANFD_CFG_TSEG2(tseg2)); + + rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg); + netdev_dbg(priv->ndev, + "rate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", + brp, sjw, tseg1, tseg2); + } } static int rcar_canfd_start(struct net_device *ndev) @@ -1233,27 +1325,37 @@ static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb, if (cf->can_id & CAN_RTR_FLAG) id |= RCANFD_CFID_CFRTR; - rcar_canfd_write(priv->base, - RCANFD_F_CFID(ch, RCANFD_CFFIFO_IDX), id); dlc = RCANFD_CFPTR_CFDLC(can_len2dlc(cf->len)); - rcar_canfd_write(priv->base, - RCANFD_F_CFPTR(ch, RCANFD_CFFIFO_IDX), dlc); - if (can_is_canfd_skb(skb)) { - /* CAN FD frame format */ - sts |= RCANFD_CFFDCSTS_CFFDF; - if (cf->flags & CANFD_BRS) - sts |= RCANFD_CFFDCSTS_CFBRS; + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + rcar_canfd_write(priv->base, + RCANFD_F_CFID(ch, RCANFD_CFFIFO_IDX), id); + rcar_canfd_write(priv->base, + RCANFD_F_CFPTR(ch, RCANFD_CFFIFO_IDX), dlc); - if (priv->can.state == CAN_STATE_ERROR_PASSIVE) - sts |= RCANFD_CFFDCSTS_CFESI; - } + if (can_is_canfd_skb(skb)) { + /* CAN FD frame format */ + sts |= RCANFD_CFFDCSTS_CFFDF; + if (cf->flags & CANFD_BRS) + sts |= RCANFD_CFFDCSTS_CFBRS; - rcar_canfd_write(priv->base, RCANFD_F_CFFDCSTS(ch, RCANFD_CFFIFO_IDX), - sts); + if (priv->can.state == CAN_STATE_ERROR_PASSIVE) + sts |= RCANFD_CFFDCSTS_CFESI; + } + + rcar_canfd_write(priv->base, + RCANFD_F_CFFDCSTS(ch, RCANFD_CFFIFO_IDX), sts); - rcar_canfd_put_data(priv, cf, - RCANFD_F_CFDF(ch, RCANFD_CFFIFO_IDX, 0)); + rcar_canfd_put_data(priv, cf, + RCANFD_F_CFDF(ch, RCANFD_CFFIFO_IDX, 0)); + } else { + rcar_canfd_write(priv->base, + RCANFD_C_CFID(ch, RCANFD_CFFIFO_IDX), id); + rcar_canfd_write(priv->base, + RCANFD_C_CFPTR(ch, RCANFD_CFFIFO_IDX), dlc); + rcar_canfd_put_data(priv, cf, + RCANFD_C_CFDF(ch, RCANFD_CFFIFO_IDX, 0)); + } priv->tx_len[priv->tx_head % RCANFD_FIFO_DEPTH] = cf->len; can_put_echo_skb(skb, ndev, priv->tx_head % RCANFD_FIFO_DEPTH); @@ -1280,47 +1382,61 @@ static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv) struct net_device_stats *stats = &priv->ndev->stats; struct canfd_frame *cf; struct sk_buff *skb; - u32 sts = 0, id, ptr; + u32 sts = 0, id, dlc; u32 ch = priv->channel; u32 ridx = ch + RCANFD_RFFIFO_IDX; - id = rcar_canfd_read(priv->base, RCANFD_F_RFID(ridx)); - ptr = rcar_canfd_read(priv->base, RCANFD_F_RFPTR(ridx)); + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + id = rcar_canfd_read(priv->base, RCANFD_F_RFID(ridx)); + dlc = rcar_canfd_read(priv->base, RCANFD_F_RFPTR(ridx)); - sts = rcar_canfd_read(priv->base, RCANFD_F_RFFDSTS(ridx)); - if (sts & RCANFD_RFFDSTS_RFFDF) - skb = alloc_canfd_skb(priv->ndev, &cf); - else - skb = alloc_can_skb(priv->ndev, - (struct can_frame **)&cf); + sts = rcar_canfd_read(priv->base, RCANFD_F_RFFDSTS(ridx)); + if (sts & RCANFD_RFFDSTS_RFFDF) + skb = alloc_canfd_skb(priv->ndev, &cf); + else + skb = alloc_can_skb(priv->ndev, + (struct can_frame **)&cf); + } else { + id = rcar_canfd_read(priv->base, RCANFD_C_RFID(ridx)); + dlc = rcar_canfd_read(priv->base, RCANFD_C_RFPTR(ridx)); + skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cf); + } if (!skb) { stats->rx_dropped++; return; } - if (sts & RCANFD_RFFDSTS_RFFDF) - cf->len = can_dlc2len(RCANFD_RFPTR_RFDLC(ptr)); - else - cf->len = get_can_dlc(RCANFD_RFPTR_RFDLC(ptr)); - - if (sts & RCANFD_RFFDSTS_RFESI) { - cf->flags |= CANFD_ESI; - netdev_dbg(priv->ndev, "ESI Error\n"); - } - if (id & RCANFD_RFID_RFIDE) cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; else cf->can_id = id & CAN_SFF_MASK; - if (!(sts & RCANFD_RFFDSTS_RFFDF) && (id & RCANFD_RFID_RFRTR)) { - cf->can_id |= CAN_RTR_FLAG; - } else { - if (sts & RCANFD_RFFDSTS_RFBRS) - cf->flags |= CANFD_BRS; + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + if (sts & RCANFD_RFFDSTS_RFFDF) + cf->len = can_dlc2len(RCANFD_RFPTR_RFDLC(dlc)); + else + cf->len = get_can_dlc(RCANFD_RFPTR_RFDLC(dlc)); + + if (sts & RCANFD_RFFDSTS_RFESI) { + cf->flags |= CANFD_ESI; + netdev_dbg(priv->ndev, "ESI Error\n"); + } + + if (!(sts & RCANFD_RFFDSTS_RFFDF) && (id & RCANFD_RFID_RFRTR)) { + cf->can_id |= CAN_RTR_FLAG; + } else { + if (sts & RCANFD_RFFDSTS_RFBRS) + cf->flags |= CANFD_BRS; - rcar_canfd_get_data(priv, cf, RCANFD_F_RFDF(ridx, 0)); + rcar_canfd_get_data(priv, cf, RCANFD_F_RFDF(ridx, 0)); + } + } else { + cf->len = get_can_dlc(RCANFD_RFPTR_RFDLC(dlc)); + if (id & RCANFD_RFID_RFRTR) + cf->can_id |= CAN_RTR_FLAG; + else + rcar_canfd_get_data(priv, cf, RCANFD_C_RFDF(ridx, 0)); } /* Write 0xff to RFPC to increment the CPU-side @@ -1428,13 +1544,19 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, priv->can.clock.freq = fcan_freq; dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq); - priv->can.bittiming_const = &rcar_canfd_nom_bittiming_const; - priv->can.data_bittiming_const = - &rcar_canfd_data_bittiming_const; + if (gpriv->fdmode) { + priv->can.bittiming_const = &rcar_canfd_nom_bittiming_const; + priv->can.data_bittiming_const = + &rcar_canfd_data_bittiming_const; - /* Controller starts in CAN FD only mode */ - can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD); - priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING; + /* Controller starts in CAN FD only mode */ + can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD); + priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING; + } else { + /* Controller starts in Classical CAN only mode */ + priv->can.bittiming_const = &rcar_canfd_bittiming_const; + priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING; + } priv->can.do_set_mode = rcar_canfd_do_set_mode; priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter; @@ -1482,6 +1604,10 @@ static int rcar_canfd_probe(struct platform_device *pdev) struct device_node *of_child; unsigned long channels_mask = 0; int err, ch_irq, g_irq; + bool fdmode = true; /* CAN FD only mode - default */ + + if (of_property_read_bool(pdev->dev.of_node, "renesas,no-can-fd")) + fdmode = false; /* Classical CAN only mode */ of_child = of_get_child_by_name(pdev->dev.of_node, "channel0"); if (of_child && of_device_is_available(of_child)) @@ -1513,6 +1639,7 @@ static int rcar_canfd_probe(struct platform_device *pdev) } gpriv->pdev = pdev; gpriv->channels_mask = channels_mask; + gpriv->fdmode = fdmode; /* Peripheral clock */ gpriv->clkp = devm_clk_get(&pdev->dev, "fck"); @@ -1623,8 +1750,8 @@ static int rcar_canfd_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, gpriv); - dev_info(&pdev->dev, "global operational state (clk %d)\n", - gpriv->fcan); + dev_info(&pdev->dev, "global operational state (clk %d, fdmode %d)\n", + gpriv->fcan, gpriv->fdmode); return 0; fail_channel: -- cgit v1.3-14-g43fede From 27bfa8893b15a3fa22a593c90a48c8bcb1f9c75b Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 23 Jun 2016 16:39:44 +0900 Subject: regulator: pwm: Support for enable GPIO Add an optional enable GPIO to the pwm-regulator driver. Signed-off-by: Alexandre Courbot Signed-off-by: Mark Brown --- .../bindings/regulator/pwm-regulator.txt | 7 +++++- drivers/regulator/pwm-regulator.c | 26 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt index ed936f0f34f2..dd6f59cf1455 100644 --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt @@ -38,13 +38,18 @@ NB: To be clear, if voltage-table is provided, then the device will be used in Voltage Table Mode. If no voltage-table is provided, then the device will be used in Continuous Voltage Mode. +Optional properties: +-------------------- +- enable-gpios: GPIO to use to enable/disable the regulator + Any property defined as part of the core regulator binding can also be used. (See: ../regulator/regulator.txt) -Continuous Voltage Example: +Continuous Voltage With Enable GPIO Example: pwm_regulator { compatible = "pwm-regulator; pwms = <&pwm1 0 8448 0>; + enable-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; regulator-min-microvolt = <1016000>; regulator-max-microvolt = <1114000>; regulator-name = "vdd_logic"; diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index ab3cc0235843..90f8b7fd0437 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -20,6 +20,7 @@ #include #include #include +#include struct pwm_regulator_data { /* Shared */ @@ -38,6 +39,9 @@ struct pwm_regulator_data { /* Continuous voltage */ int volt_uV; + + /* Enable GPIO */ + struct gpio_desc *enb_gpio; }; struct pwm_voltages { @@ -94,6 +98,9 @@ static int pwm_regulator_enable(struct regulator_dev *dev) { struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + if (drvdata->enb_gpio) + gpiod_set_value_cansleep(drvdata->enb_gpio, 1); + return pwm_enable(drvdata->pwm); } @@ -103,6 +110,9 @@ static int pwm_regulator_disable(struct regulator_dev *dev) pwm_disable(drvdata->pwm); + if (drvdata->enb_gpio) + gpiod_set_value_cansleep(drvdata->enb_gpio, 0); + return 0; } @@ -110,6 +120,9 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev) { struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio)) + return false; + return pwm_is_enabled(drvdata->pwm); } @@ -248,6 +261,7 @@ static int pwm_regulator_probe(struct platform_device *pdev) struct regulator_dev *regulator; struct regulator_config config = { }; struct device_node *np = pdev->dev.of_node; + enum gpiod_flags gpio_flags; int ret; if (!np) { @@ -285,6 +299,18 @@ static int pwm_regulator_probe(struct platform_device *pdev) return ret; } + if (init_data->constraints.boot_on || init_data->constraints.always_on) + gpio_flags = GPIOD_OUT_HIGH; + else + gpio_flags = GPIOD_OUT_LOW; + drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", + gpio_flags); + if (IS_ERR(drvdata->enb_gpio)) { + ret = PTR_ERR(drvdata->enb_gpio); + dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret); + return ret; + } + /* * FIXME: pwm_apply_args() should be removed when switching to the * atomic PWM API. -- cgit v1.3-14-g43fede From 05f33bc5d6df03426e631cea5d1a8568d43ab07f Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 21 Jun 2016 16:50:13 -0700 Subject: ASoC: cs53l30: Add MUTE pin control support via GPIO The codec chip has a physical MUTE pin to let users control it via GPIO. So this patch add a mute control support to the driver. Signed-off-by: Nicolin Chen Acked-by: Paul Handrigan Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/cs53l30.txt | 4 +++ sound/soc/codecs/cs53l30.c | 30 ++++++++++++++++++++++ sound/soc/codecs/cs53l30.h | 1 + 3 files changed, 35 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/cs53l30.txt b/Documentation/devicetree/bindings/sound/cs53l30.txt index 18d6b99e0a2d..4dbfb8274cd9 100644 --- a/Documentation/devicetree/bindings/sound/cs53l30.txt +++ b/Documentation/devicetree/bindings/sound/cs53l30.txt @@ -13,6 +13,10 @@ Optional properties: - reset-gpios : a GPIO spec for the reset pin. + - mute-gpios : a GPIO spec for the MUTE pin. The active state can be either + GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW, which would be handled + by the driver automatically. + - cirrus,micbias-lvl : Set the output voltage level on the MICBIAS Pin. 0 = Hi-Z 1 = 1.80 V diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index b0a64a19a045..5988b5c672fe 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -35,6 +35,7 @@ struct cs53l30_private { struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES]; struct regmap *regmap; struct gpio_desc *reset_gpio; + struct gpio_desc *mute_gpio; struct clk *mclk; bool use_sdout2; u32 mclk_rate; @@ -833,6 +834,16 @@ static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai, return 0; } +static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); + + if (priv->mute_gpio) + gpiod_set_value_cansleep(priv->mute_gpio, mute); + + return 0; +} + /* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ #define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) @@ -846,6 +857,7 @@ static const struct snd_soc_dai_ops cs53l30_ops = { .set_sysclk = cs53l30_set_sysclk, .set_tristate = cs53l30_set_tristate, .set_tdm_slot = cs53l30_set_dai_tdm_slot, + .mute_stream = cs53l30_mute_stream, }; static struct snd_soc_dai_driver cs53l30_dai = { @@ -991,6 +1003,24 @@ static int cs53l30_i2c_probe(struct i2c_client *client, cs53l30->mclk = NULL; } + /* Fetch the MUTE control */ + cs53l30->mute_gpio = devm_gpiod_get_optional(dev, "mute", + GPIOD_OUT_HIGH); + if (IS_ERR(cs53l30->mute_gpio)) { + ret = PTR_ERR(cs53l30->mute_gpio); + goto error; + } + + if (cs53l30->mute_gpio) { + /* Enable MUTE controls via MUTE pin */ + regmap_write(cs53l30->regmap, CS53L30_MUTEP_CTL1, + CS53L30_MUTEP_CTL1_MUTEALL); + /* Flip the polarity of MUTE pin */ + if (gpiod_is_active_low(cs53l30->mute_gpio)) + regmap_update_bits(cs53l30->regmap, CS53L30_MUTEP_CTL2, + CS53L30_MUTE_PIN_POLARITY, 0); + } + if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val)) regmap_update_bits(cs53l30->regmap, CS53L30_MICBIAS_CTL, CS53L30_MIC_BIAS_CTRL_MASK, val); diff --git a/sound/soc/codecs/cs53l30.h b/sound/soc/codecs/cs53l30.h index 0dd4afbb5c64..5e39da568749 100644 --- a/sound/soc/codecs/cs53l30.h +++ b/sound/soc/codecs/cs53l30.h @@ -253,6 +253,7 @@ #define CS53L30_MUTE_MB_ALL_PDN_MASK (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) #define CS53L30_MUTE_MB_ALL_PDN (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT) +#define CS53L30_MUTEP_CTL1_MUTEALL (0xdf) #define CS53L30_MUTEP_CTL1_DEFAULT (0) /* R32 (0x20) CS53L30_MUTEP_CTL2 - MUTE Pin Control 2 */ -- cgit v1.3-14-g43fede From 0cea220cf739c8b64d1d9ad75f4817621d3dc897 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 22 Jun 2016 15:14:15 +0300 Subject: Documentation/sphinx: drop modindex, we don't have python modules The modindex is for python modules. Signed-off-by: Jani Nikula --- Documentation/index.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/index.rst b/Documentation/index.rst index 71a276f34c7f..1139a7ea39ec 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -18,6 +18,4 @@ Indices and tables ================== * :ref:`genindex` -* :ref:`modindex` * :ref:`search` - -- cgit v1.3-14-g43fede From ebc88ef05c825024a5d95285459b8c842c095c0f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 22 Jun 2016 15:41:48 +0300 Subject: Documentation: add top level 'make help' output for Sphinx While there's slight overlap with the DocBook help now, this can stay intact when the DocBook help goes away. Signed-off-by: Jani Nikula --- Documentation/DocBook/Makefile | 4 ++-- Documentation/Makefile.sphinx | 8 ++++++++ Makefile | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index e0c7e1e0590b..496d4295ec38 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -218,7 +218,7 @@ silent_gen_xml = : ### # Help targets as used by the top-level makefile dochelp: - @echo ' Linux kernel internal documentation in different formats:' + @echo ' Linux kernel internal documentation in different formats (DocBook):' @echo ' htmldocs - HTML' @echo ' pdfdocs - PDF' @echo ' psdocs - Postscript' @@ -227,7 +227,7 @@ dochelp: @echo ' installmandocs - install man pages generated by mandocs' @echo ' cleandocs - clean all generated DocBook files' @echo - @echo 'make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml' + @echo ' make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml' @echo ' valid values for DOCBOOKS are: $(DOCBOOKS)' diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index addf32309bc3..810c11f0d37f 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -60,4 +60,12 @@ installmandocs: cleandocs: $(Q)rm -rf $(BUILDDIR) +dochelp: + @echo ' Linux kernel internal documentation in different formats (Sphinx):' + @echo ' htmldocs - HTML' + @echo ' pdfdocs - PDF' + @echo ' epubdocs - EPUB' + @echo ' xmldocs - XML' + @echo ' cleandocs - clean all generated files' + endif # HAVE_SPHINX diff --git a/Makefile b/Makefile index 8908a51b895a..f7f393c40886 100644 --- a/Makefile +++ b/Makefile @@ -1364,6 +1364,8 @@ help: @$(MAKE) $(build)=$(package-dir) help @echo '' @echo 'Documentation targets:' + @$(MAKE) -f $(srctree)/Documentation/Makefile.sphinx dochelp + @echo '' @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp @echo '' @echo 'Architecture specific targets ($(SRCARCH)):' -- cgit v1.3-14-g43fede From c9b2ffc02287771e70eb27132c47df6d5c7d91fb Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Fri, 11 Mar 2016 23:04:19 -0800 Subject: bcache: documentation updates and corrections Bcache documentation updates: - Added new HOWTO/COOKBOOK section - fixed a few typos - /sys/block/bcache0/cache_mode is /sys/block/bcache0/bcache/cache_mode Signed-off-by: Marc MERLIN Signed-off-by: Jonathan Corbet --- Documentation/bcache.txt | 160 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 152 insertions(+), 8 deletions(-) (limited to 'Documentation') diff --git a/Documentation/bcache.txt b/Documentation/bcache.txt index 32b6c3189d98..0aba405d3368 100644 --- a/Documentation/bcache.txt +++ b/Documentation/bcache.txt @@ -1,4 +1,4 @@ -Say you've got a big slow raid 6, and an X-25E or three. Wouldn't it be +Say you've got a big slow raid 6, and an ssd or three. Wouldn't it be nice if you could use them as cache... Hence bcache. Wiki and git repositories are at: @@ -8,7 +8,7 @@ Wiki and git repositories are at: It's designed around the performance characteristics of SSDs - it only allocates in erase block sized buckets, and it uses a hybrid btree/log to track cached -extants (which can be anywhere from a single sector to the bucket size). It's +extents (which can be anywhere from a single sector to the bucket size). It's designed to avoid random writes at all costs; it fills up an erase block sequentially, then issues a discard before reusing it. @@ -55,7 +55,10 @@ immediately. Without udev, you can manually register devices like this: Registering the backing device makes the bcache device show up in /dev; you can now format it and use it as normal. But the first time using a new bcache device, it'll be running in passthrough mode until you attach it to a cache. -See the section on attaching. +If you are thinking about using bcache later, it is recommended to setup all your +slow devices as bcache backing devices without a cache, and you can choose to add +a caching device later. +See 'ATTACHING' section below. The devices show up as: @@ -72,12 +75,14 @@ To get started: mount /dev/bcache0 /mnt You can control bcache devices through sysfs at /sys/block/bcache/bcache . +You can also control them through /sys/fs//bcache// . Cache devices are managed as sets; multiple caches per set isn't supported yet but will allow for mirroring of metadata and dirty data in the future. Your new cache set shows up as /sys/fs/bcache/ -ATTACHING: +ATTACHING +--------- After your cache device and backing device are registered, the backing device must be attached to your cache set to enable caching. Attaching a backing @@ -105,7 +110,8 @@ but all the cached data will be invalidated. If there was dirty data in the cache, don't expect the filesystem to be recoverable - you will have massive filesystem corruption, though ext4's fsck does work miracles. -ERROR HANDLING: +ERROR HANDLING +-------------- Bcache tries to transparently handle IO errors to/from the cache device without affecting normal operation; if it sees too many errors (the threshold is @@ -127,7 +133,143 @@ the backing devices to passthrough mode. writeback mode). It currently doesn't do anything intelligent if it fails to read some of the dirty data, though. -TROUBLESHOOTING PERFORMANCE: + +HOWTO/COOKBOOK +-------------- + +A) Your bcache doesn't start. + Starting and starting a bcache with a missing caching device + +Registering the backing device doesn't help, it's already there, you just need +to force it to run without the cache: +host:~# echo /dev/sdb1 > /sys/fs/bcache/register +[ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered + +Next, you try to register your caching device if it's present. However if it's +absent, or registration fails for some reason, you can still start your bcache +without its cache, like so: +host:/sys/block/sdb/sdb1/bcache# echo 1 > running + + +B) Bcache not finding its cache and not starting + +This does not work: +host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach +[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set +[ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8 +[ 1933.478179] : cache set not found + +In this case, the caching device was simply not registered at boot or +disappeared and came back, and needs to be (re-)registered: +host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register + + +C) Corrupt bcache caching device crashes the kernel on startup/boot + +You'll have to wipe the caching device, start the backing device without the +cache, and you can re-attach the cleaned up caching device then. This does +require booting with a kernel/rescue media where bcache is disabled +since it will otherwise try to access your device and probably crash +again before you have a chance to wipe it. +(or if you plan ahead, compile a backup kernel with bcache disabled and keep it +in your grub config for a rainy day) +If bcache is not available in the kernel, a filesystem on the backing device is +still available at an 8KiB offset. So either via a loopdev of the backing device +created with --offset 8K or by temporarily increasing the start sector of the +partition by 16 (512byte sectors). + +This is how you wipe the caching device: +host:~# wipefs -a /dev/sdh2 +16 bytes were erased at offset 0x1018 (bcache) +they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + +After you boot back with bcache enabled, you recreate the cache and attach it: +host:~# make-bcache -C /dev/sdh2 +UUID: 7be7e175-8f4c-4f99-94b2-9c904d227045 +Set UUID: 5bc072a8-ab17-446d-9744-e247949913c1 +version: 0 +nbuckets: 106874 +block_size: 1 +bucket_size: 1024 +nr_in_set: 1 +nr_this_dev: 0 +first_bucket: 1 +[ 650.511912] bcache: run_cache_set() invalidating existing data +[ 650.549228] bcache: register_cache() registered cache device sdh2 + +start backing device with missing cache: +host:/sys/block/md5/bcache# echo 1 > running + +attach new cache: +host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach +[ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1 + + +D) Remove or replace a caching device + +host:/sys/block/sda/sda7/bcache# echo 1 > detach +[ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7 + +host:~# wipefs -a /dev/nvme0n1p4 +wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy +Ooops, it's disabled, but not unregistered, so it's still protected + +We need to go and unregister it: +host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0 +lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/ +host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop +kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered + +Now we can wipe it: +host:~# wipefs -a /dev/nvme0n1p4 +/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + + +E) dmcrypt and bcache + +First setup bcache unencrypted and then install dmcrypt on top of /dev/bcache +This will work faster than if you dmcrypt both the backing and caching +devices and then install bcache on top. + + +F) Stop/free a registered bcache to wipe and/or recreate it +(or maybe you need to free up all bcache references so that you can have fdisk +run and re-register a changed partition table, which won't work if there are any +active backing or caching devices left on it) + +1) Is it present in /dev/bcache* ? (there are times where it won't be) +If so, it's easy: +host:/sys/block/bcache0/bcache# echo 1 > stop + +2) But if your backing device is gone, this won't work: +host:/sys/block/bcache0# cd bcache +bash: cd: bcache: No such file or directory + +In this case, you may have to unregister the dmcrypt block device that +references this bcache to free it up: +host:~# dmsetup remove oldds1 +bcache: bcache_device_free() bcache0 stopped +bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered + +This causes the backing bcache to be removed from /sys/fs/bcache and then it can +be reused + +3) In other cases, you can also look in /sys/fs/bcache/: +host:/sys/fs/bcache# ls -l */{cache?,bdev?} +lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/ +lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache0 -> ../../../devices/virtual/block/dm-4/bcache/ +lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdl/sdl2/bcache/ + +The device names will show which UUID is relevant, cd in that directory +and stop the cache: +host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop +this will free up bcache references and let you reuse the partition for other +purposes. + + + +TROUBLESHOOTING PERFORMANCE +--------------------------- Bcache has a bunch of config options and tunables. The defaults are intended to be reasonable for typical desktop and server workloads, but they're not what you @@ -140,7 +282,7 @@ want for getting the best possible numbers when benchmarking. maturity, but simply because in writeback mode you'll lose data if something happens to your SSD) - # echo writeback > /sys/block/bcache0/cache_mode + # echo writeback > /sys/block/bcache0/bcache/cache_mode - Bad performance, or traffic not going to the SSD that you'd expect @@ -193,7 +335,9 @@ want for getting the best possible numbers when benchmarking. Solution: warm the cache by doing writes, or use the testing branch (there's a fix for the issue there). -SYSFS - BACKING DEVICE: + +SYSFS - BACKING DEVICE +---------------------- Available at /sys/block//bcache, /sys/block/bcache*/bcache and (if attached) /sys/fs/bcache//bdev* -- cgit v1.3-14-g43fede From c0b8c9a3447ad379869f21884b86ec97c7b8db7a Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Fri, 11 Mar 2016 23:43:47 -0800 Subject: bcache: documentation formatting, edited for clarity, stripe alignment notes Signed-off-by: Eric Wheeler Cc: Marc MERLIN Signed-off-by: Jonathan Corbet --- Documentation/bcache.txt | 161 ++++++++++++++++++++++++++++------------------- 1 file changed, 97 insertions(+), 64 deletions(-) (limited to 'Documentation') diff --git a/Documentation/bcache.txt b/Documentation/bcache.txt index 0aba405d3368..a9259b562d5c 100644 --- a/Documentation/bcache.txt +++ b/Documentation/bcache.txt @@ -137,48 +137,60 @@ the backing devices to passthrough mode. HOWTO/COOKBOOK -------------- -A) Your bcache doesn't start. - Starting and starting a bcache with a missing caching device +A) Starting a bcache with a missing caching device -Registering the backing device doesn't help, it's already there, you just need +If registering the backing device doesn't help, it's already there, you just need to force it to run without the cache: -host:~# echo /dev/sdb1 > /sys/fs/bcache/register -[ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered + host:~# echo /dev/sdb1 > /sys/fs/bcache/register + [ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered -Next, you try to register your caching device if it's present. However if it's -absent, or registration fails for some reason, you can still start your bcache -without its cache, like so: -host:/sys/block/sdb/sdb1/bcache# echo 1 > running +Next, you try to register your caching device if it's present. However +if it's absent, or registration fails for some reason, you can still +start your bcache without its cache, like so: + host:/sys/block/sdb/sdb1/bcache# echo 1 > running +Note that this may cause data loss if you were running in writeback mode. -B) Bcache not finding its cache and not starting -This does not work: -host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach -[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set -[ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8 -[ 1933.478179] : cache set not found +B) Bcache does not find its cache -In this case, the caching device was simply not registered at boot or -disappeared and came back, and needs to be (re-)registered: -host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register + host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach + [ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set + [ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8 + [ 1933.478179] : cache set not found +In this case, the caching device was simply not registered at boot +or disappeared and came back, and needs to be (re-)registered: + host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register -C) Corrupt bcache caching device crashes the kernel on startup/boot -You'll have to wipe the caching device, start the backing device without the -cache, and you can re-attach the cleaned up caching device then. This does -require booting with a kernel/rescue media where bcache is disabled -since it will otherwise try to access your device and probably crash -again before you have a chance to wipe it. -(or if you plan ahead, compile a backup kernel with bcache disabled and keep it -in your grub config for a rainy day) -If bcache is not available in the kernel, a filesystem on the backing device is -still available at an 8KiB offset. So either via a loopdev of the backing device -created with --offset 8K or by temporarily increasing the start sector of the -partition by 16 (512byte sectors). +C) Corrupt bcache crashes the kernel at device registration time: + +This should never happen. If it does happen, then you have found a bug! +Please report it to the bcache development list: linux-bcache@vger.kernel.org + +Be sure to provide as much information that you can including kernel dmesg +output if available so that we may assist. + + +D) Recovering data without bcache: + +If bcache is not available in the kernel, a filesystem on the backing +device is still available at an 8KiB offset. So either via a loopdev +of the backing device created with --offset 8K, or any value defined by +--data-offset when you originally formatted bcache with `make-bcache`. + +For example: + losetup -o 8192 /dev/loop0 /dev/your_bcache_backing_dev + +This should present your unmodified backing device data in /dev/loop0 + +If your cache is in writethrough mode, then you can safely discard the +cache device without loosing data. + + +E) Wiping a cache device -This is how you wipe the caching device: host:~# wipefs -a /dev/sdh2 16 bytes were erased at offset 0x1018 (bcache) they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 @@ -205,56 +217,60 @@ host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach [ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1 -D) Remove or replace a caching device +F) Remove or replace a caching device -host:/sys/block/sda/sda7/bcache# echo 1 > detach -[ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7 + host:/sys/block/sda/sda7/bcache# echo 1 > detach + [ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7 -host:~# wipefs -a /dev/nvme0n1p4 -wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy -Ooops, it's disabled, but not unregistered, so it's still protected + host:~# wipefs -a /dev/nvme0n1p4 + wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy + Ooops, it's disabled, but not unregistered, so it's still protected We need to go and unregister it: -host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0 -lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/ -host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop -kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered + host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0 + lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/ + host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop + kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered Now we can wipe it: -host:~# wipefs -a /dev/nvme0n1p4 -/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + host:~# wipefs -a /dev/nvme0n1p4 + /dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + +G) dm-crypt and bcache -E) dmcrypt and bcache +First setup bcache unencrypted and then install dmcrypt on top of +/dev/bcache This will work faster than if you dmcrypt both the backing +and caching devices and then install bcache on top. [benchmarks?] -First setup bcache unencrypted and then install dmcrypt on top of /dev/bcache -This will work faster than if you dmcrypt both the backing and caching -devices and then install bcache on top. +H) Stop/free a registered bcache to wipe and/or recreate it -F) Stop/free a registered bcache to wipe and/or recreate it -(or maybe you need to free up all bcache references so that you can have fdisk -run and re-register a changed partition table, which won't work if there are any -active backing or caching devices left on it) +Suppose that you need to free up all bcache references so that you can +fdisk run and re-register a changed partition table, which won't work +if there are any active backing or caching devices left on it: 1) Is it present in /dev/bcache* ? (there are times where it won't be) + If so, it's easy: -host:/sys/block/bcache0/bcache# echo 1 > stop + host:/sys/block/bcache0/bcache# echo 1 > stop 2) But if your backing device is gone, this won't work: -host:/sys/block/bcache0# cd bcache -bash: cd: bcache: No such file or directory + host:/sys/block/bcache0# cd bcache + bash: cd: bcache: No such file or directory In this case, you may have to unregister the dmcrypt block device that references this bcache to free it up: -host:~# dmsetup remove oldds1 -bcache: bcache_device_free() bcache0 stopped -bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered + host:~# dmsetup remove oldds1 + bcache: bcache_device_free() bcache0 stopped + bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered -This causes the backing bcache to be removed from /sys/fs/bcache and then it can -be reused +This causes the backing bcache to be removed from /sys/fs/bcache and +then it can be reused. This would be true of any block device stacking +where bcache is a lower device. 3) In other cases, you can also look in /sys/fs/bcache/: + host:/sys/fs/bcache# ls -l */{cache?,bdev?} lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/ lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache0 -> ../../../devices/virtual/block/dm-4/bcache/ @@ -262,9 +278,10 @@ lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache The device names will show which UUID is relevant, cd in that directory and stop the cache: -host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop -this will free up bcache references and let you reuse the partition for other -purposes. + host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop + +This will free up bcache references and let you reuse the partition for +other purposes. @@ -275,6 +292,22 @@ Bcache has a bunch of config options and tunables. The defaults are intended to be reasonable for typical desktop and server workloads, but they're not what you want for getting the best possible numbers when benchmarking. + - Backing device alignment + + The default metadata size in bcache is 8k. If your backing device is + RAID based, then be sure to align this by a multiple of your stride + width using `make-bcache --data-offset`. If you intend to expand your + disk array in the future, then multiply a series of primes by your + raid stripe size to get the disk multiples that you would like. + + For example: If you have a 64k stripe size, then the following offset + would provide alignment for many common RAID5 data spindle counts: + 64k * 2*2*2*3*3*5*7 bytes = 161280k + + That space is wasted, but for only 157.5MB you can grow your RAID 5 + volume to the following data-spindle counts without re-aligning: + 3,4,5,6,7,8,9,10,12,14,15,18,20,21 ... + - Bad write performance If write performance is not what you expected, you probably wanted to be @@ -382,7 +415,7 @@ sequential_merge against all new requests to determine which new requests are sequential continuations of previous requests for the purpose of determining sequential cutoff. This is necessary if the sequential cutoff value is greater than the - maximum acceptable sequential size for any single request. + maximum acceptable sequential size for any single request. state The backing device can be in one of four different states: @@ -469,7 +502,7 @@ bucket_size Size of buckets cache<0..n> - Symlink to each of the cache devices comprising this cache set. + Symlink to each of the cache devices comprising this cache set. cache_available_percent Percentage of cache device which doesn't contain dirty data, and could -- cgit v1.3-14-g43fede From a37376f32687cb4043e72f5f761df5cc52e08073 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 17 Jun 2016 09:40:02 +0800 Subject: Documentation: fix wrong value in md.txt In the current Documentation/md.txt, the lower limit value of stripe_cache_size is 16 and the default value is 128, but when I update kernel to the latest mainline version and RAID5 array is created by mdadm, then execute the following commands, it shows an error and a difference respectively. 1) set stripe_cache_size to 16 [root@localhost ~]# echo 16 > /sys/block/md0/md/stripe_cache_size bash: echo: write error: Invalid argument 2) read the default value of stripe_cache_size [root@localhost ~]# cat /sys/block/md0/md/stripe_cache_size 256 I read drivers/md/raid5.c and find the following related code: 1) in function 'raid5_set_cache_size': if (size <= 16 || size > 32768) return -EINVAL; 2) #define NR_STRIPES 256 So the lower limit value of stripe_cache_size should be 17 and the default value should be 256. Signed-off-by: Tiezhu Yang Signed-off-by: Jonathan Corbet --- Documentation/md.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/md.txt b/Documentation/md.txt index 1a2ada46aaed..d6e2fcf27337 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt @@ -602,7 +602,7 @@ These currently include stripe_cache_size (currently raid5 only) number of entries in the stripe cache. This is writable, but - there are upper and lower limits (32768, 16). Default is 128. + there are upper and lower limits (32768, 17). Default is 256. strip_cache_active (currently raid5 only) number of active entries in the stripe cache preread_bypass_threshold (currently raid5 only) -- cgit v1.3-14-g43fede From 072baa037110bbb814b342cd478fe3ffdf84fdf9 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Sat, 11 Jun 2016 02:56:37 +0200 Subject: Documentation: tiny typo fix in usb/gadget_multi.txt Signed-off-by: Michal Nazarewicz Signed-off-by: Jonathan Corbet --- Documentation/usb/gadget_multi.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/usb/gadget_multi.txt b/Documentation/usb/gadget_multi.txt index 5faf514047e9..b3146dd7aa43 100644 --- a/Documentation/usb/gadget_multi.txt +++ b/Documentation/usb/gadget_multi.txt @@ -36,7 +36,7 @@ configuration with CDC ECM which should work better under Linux. ** Windows host drivers -For the gadget two work under Windows two conditions have to be met: +For the gadget to work under Windows two conditions have to be met: *** Detecting as composite gadget -- cgit v1.3-14-g43fede From 3183ab8997a477c8d9ad175a1cef70dff77c6dbc Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 22 Jun 2016 13:26:10 +0200 Subject: netfilter: conntrack: allow increasing bucket size via sysctl too No need to restrict this to module parameter. We export a copy of the real hash size -- when user alters the value we allocate the new table, copy entries etc before we update the real size to the requested one. This is also needed because the real size is used by concurrent readers and cannot be changed without synchronizing the conntrack generation seqcnt. We only allow changing this value from the initial net namespace. Tested using http-client-benchmark vs. httpterm with concurrent while true;do echo $RANDOM > /proc/sys/net/netfilter/nf_conntrack_buckets done Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- Documentation/networking/nf_conntrack-sysctl.txt | 3 +- include/net/netfilter/nf_conntrack.h | 1 + net/netfilter/nf_conntrack_core.c | 41 ++++++++++++++++-------- net/netfilter/nf_conntrack_standalone.c | 36 ++++++++++++++++++--- 4 files changed, 62 insertions(+), 19 deletions(-) (limited to 'Documentation') diff --git a/Documentation/networking/nf_conntrack-sysctl.txt b/Documentation/networking/nf_conntrack-sysctl.txt index f55599c62c9d..4fb51d32fccc 100644 --- a/Documentation/networking/nf_conntrack-sysctl.txt +++ b/Documentation/networking/nf_conntrack-sysctl.txt @@ -7,12 +7,13 @@ nf_conntrack_acct - BOOLEAN Enable connection tracking flow accounting. 64-bit byte and packet counters per flow are added. -nf_conntrack_buckets - INTEGER (read-only) +nf_conntrack_buckets - INTEGER Size of hash table. If not specified as parameter during module loading, the default size is calculated by dividing total memory by 16384 to determine the number of buckets but the hash table will never have fewer than 32 and limited to 16384 buckets. For systems with more than 4GB of memory it will be 65536 buckets. + This sysctl is only writeable in the initial net namespace. nf_conntrack_checksum - BOOLEAN 0 - disabled diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 9c0ed3d7af89..5d3397f34583 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -290,6 +290,7 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb) struct kernel_param; int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); +int nf_conntrack_hash_resize(unsigned int hashsize); extern unsigned int nf_conntrack_htable_size; extern unsigned int nf_conntrack_max; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index a459176c3253..e17d5c7faca0 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1595,24 +1595,14 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) } EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable); -int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) +int nf_conntrack_hash_resize(unsigned int hashsize) { - int i, bucket, rc; - unsigned int hashsize, old_size; + int i, bucket; + unsigned int old_size; struct hlist_nulls_head *hash, *old_hash; struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; - if (current->nsproxy->net_ns != &init_net) - return -EOPNOTSUPP; - - /* On boot, we can set this without any fancy locking. */ - if (!nf_conntrack_htable_size) - return param_set_uint(val, kp); - - rc = kstrtouint(val, 0, &hashsize); - if (rc) - return rc; if (!hashsize) return -EINVAL; @@ -1620,6 +1610,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) if (!hash) return -ENOMEM; + old_size = nf_conntrack_htable_size; + if (old_size == hashsize) { + nf_ct_free_hashtable(hash, hashsize); + return 0; + } + local_bh_disable(); nf_conntrack_all_lock(); write_seqcount_begin(&nf_conntrack_generation); @@ -1655,6 +1651,25 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) nf_ct_free_hashtable(old_hash, old_size); return 0; } + +int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) +{ + unsigned int hashsize; + int rc; + + if (current->nsproxy->net_ns != &init_net) + return -EOPNOTSUPP; + + /* On boot, we can set this without any fancy locking. */ + if (!nf_conntrack_htable_size) + return param_set_uint(val, kp); + + rc = kstrtouint(val, 0, &hashsize); + if (rc) + return rc; + + return nf_conntrack_hash_resize(hashsize); +} EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index f87e84ebcec3..a0cc1919f081 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -434,8 +434,29 @@ static void nf_conntrack_standalone_fini_proc(struct net *net) #ifdef CONFIG_SYSCTL /* Log invalid packets of a given protocol */ -static int log_invalid_proto_min = 0; -static int log_invalid_proto_max = 255; +static int log_invalid_proto_min __read_mostly; +static int log_invalid_proto_max __read_mostly = 255; + +/* size the user *wants to set */ +static unsigned int nf_conntrack_htable_size_user __read_mostly; + +static int +nf_conntrack_hash_sysctl(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (ret < 0 || !write) + return ret; + + /* update ret, we might not be able to satisfy request */ + ret = nf_conntrack_hash_resize(nf_conntrack_htable_size_user); + + /* update it to the actual value used by conntrack */ + nf_conntrack_htable_size_user = nf_conntrack_htable_size; + return ret; +} static struct ctl_table_header *nf_ct_netfilter_header; @@ -456,10 +477,10 @@ static struct ctl_table nf_ct_sysctl_table[] = { }, { .procname = "nf_conntrack_buckets", - .data = &nf_conntrack_htable_size, + .data = &nf_conntrack_htable_size_user, .maxlen = sizeof(unsigned int), - .mode = 0444, - .proc_handler = proc_dointvec, + .mode = 0644, + .proc_handler = nf_conntrack_hash_sysctl, }, { .procname = "nf_conntrack_checksum", @@ -517,6 +538,9 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net) if (net->user_ns != &init_user_ns) table[0].procname = NULL; + if (!net_eq(&init_net, net)) + table[2].mode = 0444; + net->ct.sysctl_header = register_net_sysctl(net, "net/netfilter", table); if (!net->ct.sysctl_header) goto out_unregister_netfilter; @@ -606,6 +630,8 @@ static int __init nf_conntrack_standalone_init(void) ret = -ENOMEM; goto out_sysctl; } + + nf_conntrack_htable_size_user = nf_conntrack_htable_size; #endif ret = register_pernet_subsys(&nf_conntrack_net_ops); -- cgit v1.3-14-g43fede From 17defc282fe6e6ac93edbad8873ce89ef86b2490 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 23 Jun 2016 15:36:04 +0300 Subject: Documentation: add meta-documentation for Sphinx and kernel-doc Describe Sphinx, reStructuredText, the kernel-doc extension, the kernel-doc structured documentation comments, etc. The kernel-doc parts are based on kernel-doc-nano-HOWTO.txt, by Tim . Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- Documentation/index.rst | 1 + Documentation/kernel-documentation.rst | 562 +++++++++++++++++++++++++++++++++ 2 files changed, 563 insertions(+) create mode 100644 Documentation/kernel-documentation.rst (limited to 'Documentation') diff --git a/Documentation/index.rst b/Documentation/index.rst index 1139a7ea39ec..f92854f01773 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -13,6 +13,7 @@ Contents: .. toctree:: :maxdepth: 2 + kernel-documentation Indices and tables ================== diff --git a/Documentation/kernel-documentation.rst b/Documentation/kernel-documentation.rst new file mode 100644 index 000000000000..ad3506c13b11 --- /dev/null +++ b/Documentation/kernel-documentation.rst @@ -0,0 +1,562 @@ +========================== +Linux Kernel Documentation +========================== + +Introduction +============ + +The Linux kernel uses `Sphinx`_ to generate pretty documentation from +`reStructuredText`_ files under ``Documentation``. To build the documentation in +HTML or PDF formats, use ``make htmldocs`` or ``make pdfdocs``. The generated +documentation is placed in ``Documentation/output``. + +.. _Sphinx: http://www.sphinx-doc.org/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html + +The reStructuredText files may contain directives to include structured +documentation comments, or kernel-doc comments, from source files. Usually these +are used to describe the functions and types and design of the code. The +kernel-doc comments have some special structure and formatting, but beyond that +they are also treated as reStructuredText. + +There is also the deprecated DocBook toolchain to generate documentation from +DocBook XML template files under ``Documentation/DocBook``. The DocBook files +are to be converted to reStructuredText, and the toolchain is slated to be +removed. + +Finally, there are thousands of plain text documentation files scattered around +``Documentation``. Some of these will likely be converted to reStructuredText +over time, but the bulk of them will remain in plain text. + +Sphinx Build +============ + +The usual way to generate the documentation is to run ``make htmldocs`` or +``make pdfdocs``. There are also other formats available, see the documentation +section of ``make help``. The generated documentation is placed in +format-specific subdirectories under ``Documentation/output``. + +To generate documentation, Sphinx (``sphinx-build``) must obviously be +installed. For prettier HTML output, the Read the Docs Sphinx theme +(``sphinx_rtd_theme``) is used if available. For PDF output, ``rst2pdf`` is also +needed. All of these are widely available and packaged in distributions. + +To pass extra options to Sphinx, you can use the ``SPHINXOPTS`` make +variable. For example, use ``make SPHINXOPTS=-v htmldocs`` to get more verbose +output. + +To remove the generated documentation, run ``make cleandocs``. + +Writing Documentation +===================== + +Adding new documentation can be as simple as: + +1. Add a new ``.rst`` file somewhere under ``Documentation``. +2. Refer to it from the Sphinx main `TOC tree`_ in ``Documentation/index.rst``. + +.. _TOC tree: http://www.sphinx-doc.org/en/stable/markup/toctree.html + +This is usually good enough for simple documentation (like the one you're +reading right now), but for larger documents it may be advisable to create a +subdirectory (or use an existing one). For example, the graphics subsystem +documentation is under ``Documentation/gpu``, split to several ``.rst`` files, +and has a separate ``index.rst`` (with a ``toctree`` of its own) referenced from +the main index. + +See the documentation for `Sphinx`_ and `reStructuredText`_ on what you can do +with them. In particular, the Sphinx `reStructuredText Primer`_ is a good place +to get started with reStructuredText. There are also some `Sphinx specific +markup constructs`_. + +.. _reStructuredText Primer: http://www.sphinx-doc.org/en/stable/rest.html +.. _Sphinx specific markup constructs: http://www.sphinx-doc.org/en/stable/markup/index.html + +Specific guidelines for the kernel documentation +------------------------------------------------ + +Here are some specific guidelines for the kernel documentation: + +* Please don't go overboard with reStructuredText markup. Keep it simple. + +* Please stick to this order of heading adornments: + + 1. ``=`` with overline for document title:: + + ============== + Document title + ============== + + 2. ``=`` for chapters:: + + Chapters + ======== + + 3. ``-`` for sections:: + + Section + ------- + + 4. ``~`` for subsections:: + + Subsection + ~~~~~~~~~~ + + Although RST doesn't mandate a specific order ("Rather than imposing a fixed + number and order of section title adornment styles, the order enforced will be + the order as encountered."), having the higher levels the same overall makes + it easier to follow the documents. + + +Including kernel-doc comments +============================= + +The Linux kernel source files may contain structured documentation comments, or +kernel-doc comments to describe the functions and types and design of the +code. The documentation comments may be included to any of the reStructuredText +documents using a dedicated kernel-doc Sphinx directive extension. + +The kernel-doc directive is of the format:: + + .. kernel-doc:: source + :option: + +The *source* is the path to a source file, relative to the kernel source +tree. The following directive options are supported: + +export: *[source-pattern ...]* + Include documentation for all functions in *source* that have been exported + using ``EXPORT_SYMBOL`` or ``EXPORT_SYMBOL_GPL`` either in *source* or in any + of the files specified by *source-pattern*. + + The *source-pattern* is useful when the kernel-doc comments have been placed + in header files, while ``EXPORT_SYMBOL`` and ``EXPORT_SYMBOL_GPL`` are next to + the function definitions. + + Examples:: + + .. kernel-doc:: lib/bitmap.c + :export: + + .. kernel-doc:: include/net/mac80211.h + :export: net/mac80211/*.c + +internal: *[source-pattern ...]* + Include documentation for all functions and types in *source* that have + **not** been exported using ``EXPORT_SYMBOL`` or ``EXPORT_SYMBOL_GPL`` either + in *source* or in any of the files specified by *source-pattern*. + + Example:: + + .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :internal: + +doc: *title* + Include documentation for the ``DOC:`` paragraph identified by *title* in + *source*. Spaces are allowed in *title*; do not quote the *title*. The *title* + is only used as an identifier for the paragraph, and is not included in the + output. Please make sure to have an appropriate heading in the enclosing + reStructuredText document. + + Example:: + + .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :doc: High Definition Audio over HDMI and Display Port + +functions: *function* *[...]* + Include documentation for each *function* in *source*. + + Example:: + + .. kernel-doc:: lib/bitmap.c + :functions: bitmap_parselist bitmap_parselist_user + +Without options, the kernel-doc directive includes all documentation comments +from the source file. + +The kernel-doc extension is included in the kernel source tree, at +``Documentation/sphinx/kernel-doc.py``. Internally, it uses the +``scripts/kernel-doc`` script to extract the documentation comments from the +source. + +Writing kernel-doc comments +=========================== + +In order to provide embedded, "C" friendly, easy to maintain, but consistent and +extractable overview, function and type documentation, the Linux kernel has +adopted a consistent style for documentation comments. The format for this +documentation is called the kernel-doc format, described below. This style +embeds the documentation within the source files, using a few simple conventions +for adding documentation paragraphs and documenting functions and their +parameters, structures and unions and their members, enumerations, and typedefs. + +.. note:: The kernel-doc format is deceptively similar to gtk-doc or Doxygen, + yet distinctively different, for historical reasons. The kernel source + contains tens of thousands of kernel-doc comments. Please stick to the style + described here. + +The ``scripts/kernel-doc`` script is used by the Sphinx kernel-doc extension in +the documentation build to extract this embedded documentation into the various +HTML, PDF, and other format documents. + +In order to provide good documentation of kernel functions and data structures, +please use the following conventions to format your kernel-doc comments in the +Linux kernel source. + +How to format kernel-doc comments +--------------------------------- + +The opening comment mark ``/**`` is reserved for kernel-doc comments. Only +comments so marked will be considered by the ``kernel-doc`` tool. Use it only +for comment blocks that contain kernel-doc formatted comments. The usual ``*/`` +should be used as the closing comment marker. The lines in between should be +prefixed by `` * `` (space star space). + +The function and type kernel-doc comments should be placed just before the +function or type being described. The overview kernel-doc comments may be freely +placed at the top indentation level. + +Example kernel-doc function comment:: + + /** + * foobar() - Brief description of foobar. + * @arg: Description of argument of foobar. + * + * Longer description of foobar. + * + * Return: Description of return value of foobar. + */ + int foobar(int arg) + +The format is similar for documentation for structures, enums, paragraphs, +etc. See the sections below for details. + +The kernel-doc structure is extracted from the comments, and proper `Sphinx C +Domain`_ function and type descriptions with anchors are generated for them. The +descriptions are filtered for special kernel-doc highlights and +cross-references. See below for details. + +.. _Sphinx C Domain: http://www.sphinx-doc.org/en/stable/domains.html + +Highlights and cross-references +------------------------------- + +The following special patterns are recognized in the kernel-doc comment +descriptive text and converted to proper reStructuredText markup and `Sphinx C +Domain`_ references. + +.. attention:: The below are **only** recognized within kernel-doc comments, + **not** within normal reStructuredText documents. + +``funcname()`` + Function reference. + +``@parameter`` + Name of a function parameter. (No cross-referencing, just formatting.) + +``%CONST`` + Name of a constant. (No cross-referencing, just formatting.) + +``$ENVVAR`` + Name of an environment variable. (No cross-referencing, just formatting.) + +``&struct name`` + Structure reference. + +``&enum name`` + Enum reference. + +``&typedef name`` + Typedef reference. + +``&struct_name->member`` or ``&struct_name.member`` + Structure or union member reference. The cross-reference will be to the struct + or union definition, not the member directly. + +``&name`` + A generic type reference. Prefer using the full reference described above + instead. This is mostly for legacy comments. + +Cross-referencing from reStructuredText +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To cross-reference the functions and types defined in the kernel-doc comments +from reStructuredText documents, please use the `Sphinx C Domain`_ +references. For example:: + + See function :c:func:`foo` and struct/union/enum/typedef :c:type:`bar`. + +While the type reference works with just the type name, without the +struct/union/enum/typedef part in front, you may want to use:: + + See :c:type:`struct foo `. + See :c:type:`union bar `. + See :c:type:`enum baz `. + See :c:type:`typedef meh `. + +This will produce prettier links, and is in line with how kernel-doc does the +cross-references. + +For further details, please refer to the `Sphinx C Domain`_ documentation. + +Function documentation +---------------------- + +The general format of a function and function-like macro kernel-doc comment is:: + + /** + * function_name() - Brief description of function. + * @arg1: Describe the first argument. + * @arg2: Describe the second argument. + * One can provide multiple line descriptions + * for arguments. + * + * A longer description, with more discussion of the function function_name() + * that might be useful to those using or modifying it. Begins with an + * empty comment line, and may include additional embedded empty + * comment lines. + * + * The longer description may have multiple paragraphs. + * + * Return: Describe the return value of foobar. + * + * The return value description can also have multiple paragraphs, and should + * be placed at the end of the comment block. + */ + +The brief description following the function name may span multiple lines, and +ends with an ``@argument:`` description, a blank comment line, or the end of the +comment block. + +The kernel-doc function comments describe each parameter to the function, in +order, with the ``@argument:`` descriptions. The ``@argument:`` descriptions +must begin on the very next line following the opening brief function +description line, with no intervening blank comment lines. The ``@argument:`` +descriptions may span multiple lines. The continuation lines may contain +indentation. If a function parameter is ``...`` (varargs), it should be listed +in kernel-doc notation as: ``@...:``. + +The return value, if any, should be described in a dedicated section at the end +of the comment starting with "Return:". + +Structure, union, and enumeration documentation +----------------------------------------------- + +The general format of a struct, union, and enum kernel-doc comment is:: + + /** + * struct struct_name - Brief description. + * @member_name: Description of member member_name. + * + * Description of the structure. + */ + +Below, "struct" is used to mean structs, unions and enums, and "member" is used +to mean struct and union members as well as enumerations in an enum. + +The brief description following the structure name may span multiple lines, and +ends with a ``@member:`` description, a blank comment line, or the end of the +comment block. + +The kernel-doc data structure comments describe each member of the structure, in +order, with the ``@member:`` descriptions. The ``@member:`` descriptions must +begin on the very next line following the opening brief function description +line, with no intervening blank comment lines. The ``@member:`` descriptions may +span multiple lines. The continuation lines may contain indentation. + +In-line member documentation comments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The structure members may also be documented in-line within the definition:: + + /** + * struct foo - Brief description. + * @foo: The Foo member. + */ + struct foo { + int foo; + /** + * @bar: The Bar member. + */ + int bar; + /** + * @baz: The Baz member. + * + * Here, the member description may contain several paragraphs. + */ + int baz; + } + +Private members +~~~~~~~~~~~~~~~ + +Inside a struct description, you can use the "private:" and "public:" comment +tags. Structure fields that are inside a "private:" area are not listed in the +generated output documentation. The "private:" and "public:" tags must begin +immediately following a ``/*`` comment marker. They may optionally include +comments between the ``:`` and the ending ``*/`` marker. + +Example:: + + /** + * struct my_struct - short description + * @a: first member + * @b: second member + * + * Longer description + */ + struct my_struct { + int a; + int b; + /* private: internal use only */ + int c; + }; + + +Typedef documentation +--------------------- + +The general format of a typedef kernel-doc comment is:: + + /** + * typedef type_name - Brief description. + * + * Description of the type. + */ + +Overview documentation comments +------------------------------- + +To facilitate having source code and comments close together, you can include +kernel-doc documentation blocks that are free-form comments instead of being +kernel-doc for functions, structures, unions, enums, or typedefs. This could be +used for something like a theory of operation for a driver or library code, for +example. + +This is done by using a ``DOC:`` section keyword with a section title. + +The general format of an overview or high-level documentation comment is:: + + /** + * DOC: Theory of Operation + * + * The whizbang foobar is a dilly of a gizmo. It can do whatever you + * want it to do, at any time. It reads your mind. Here's how it works. + * + * foo bar splat + * + * The only drawback to this gizmo is that is can sometimes damage + * hardware, software, or its subject(s). + */ + +The title following ``DOC:`` acts as a heading within the source file, but also +as an identifier for extracting the documentation comment. Thus, the title must +be unique within the file. + +Recommendations +--------------- + +We definitely need kernel-doc formatted documentation for functions that are +exported to loadable modules using ``EXPORT_SYMBOL`` or ``EXPORT_SYMBOL_GPL``. + +We also look to provide kernel-doc formatted documentation for functions +externally visible to other kernel files (not marked "static"). + +We also recommend providing kernel-doc formatted documentation for private (file +"static") routines, for consistency of kernel source code layout. But this is +lower priority and at the discretion of the MAINTAINER of that kernel source +file. + +Data structures visible in kernel include files should also be documented using +kernel-doc formatted comments. + +DocBook XML [DEPRECATED] +======================== + +.. attention:: + + This section describes the deprecated DocBook XML toolchain. Please do not + create new DocBook XML template files. Please consider converting existing + DocBook XML templates files to Sphinx/reStructuredText. + +Converting DocBook to Sphinx +---------------------------- + +Over time, we expect all of the documents under ``Documentation/DocBook`` to be +converted to Sphinx and reStructuredText. For most DocBook XML documents, a good +enough solution is to use the simple ``Documentation/sphinx/tmplcvt`` script, +which uses ``pandoc`` under the hood. For example:: + + $ cd Documentation/sphinx + $ ./tmplcvt ../DocBook/in.tmpl ../out.rst + +Then edit the resulting rst files to fix any remaining issues, and add the +document in the ``toctree`` in ``Documentation/index.rst``. + +Components of the kernel-doc system +----------------------------------- + +Many places in the source tree have extractable documentation in the form of +block comments above functions. The components of this system are: + +- ``scripts/kernel-doc`` + + This is a perl script that hunts for the block comments and can mark them up + directly into reStructuredText, DocBook, man, text, and HTML. (No, not + texinfo.) + +- ``Documentation/DocBook/*.tmpl`` + + These are XML template files, which are normal XML files with special + place-holders for where the extracted documentation should go. + +- ``scripts/docproc.c`` + + This is a program for converting XML template files into XML files. When a + file is referenced it is searched for symbols exported (EXPORT_SYMBOL), to be + able to distinguish between internal and external functions. + + It invokes kernel-doc, giving it the list of functions that are to be + documented. + + Additionally it is used to scan the XML template files to locate all the files + referenced herein. This is used to generate dependency information as used by + make. + +- ``Makefile`` + + The targets 'xmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used to build + DocBook XML files, PostScript files, PDF files, and html files in + Documentation/DocBook. The older target 'sgmldocs' is equivalent to 'xmldocs'. + +- ``Documentation/DocBook/Makefile`` + + This is where C files are associated with SGML templates. + +How to use kernel-doc comments in DocBook XML template files +------------------------------------------------------------ + +DocBook XML template files (\*.tmpl) are like normal XML files, except that they +can contain escape sequences where extracted documentation should be inserted. + +``!E`` is replaced by the documentation, in ````, for +functions that are exported using ``EXPORT_SYMBOL``: the function list is +collected from files listed in ``Documentation/DocBook/Makefile``. + +``!I`` is replaced by the documentation for functions that are **not** +exported using ``EXPORT_SYMBOL``. + +``!D`` is used to name additional files to search for functions +exported using ``EXPORT_SYMBOL``. + +``!F `` is replaced by the documentation, in +````, for the functions listed. + +``!P
`` is replaced by the contents of the ``DOC:`` +section titled ``
`` from ````. Spaces are allowed in +``
``; do not quote the ``
``. + +``!C`` is replaced by nothing, but makes the tools check that all DOC: +sections and documented functions, symbols, etc. are used. This makes sense to +use when you use ``!F`` or ``!P`` only and want to verify that all documentation +is included. -- cgit v1.3-14-g43fede From f103ad1556aa985eb094cdfa8a8e4d618732bad2 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Wed, 22 Jun 2016 08:58:56 -0500 Subject: Documentation: dt: socfpga: Add Arria10 Ethernet binding Add the device tree bindings needed to support the Altera Ethernet FIFO buffers on the Arria10 chip. Signed-off-by: Thor Thayer Acked-by: Rob Herring Cc: devicetree@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1466603939-7526-6-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov --- .../bindings/arm/altera/socfpga-eccmgr.txt | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt index 15eb0df1d36e..b545856a444f 100644 --- a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt +++ b/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt @@ -82,6 +82,14 @@ Required Properties: - interrupts : Should be single bit error interrupt, then double bit error interrupt, in this order. +Ethernet FIFO ECC +Required Properties: +- compatible : Should be "altr,socfpga-eth-mac-ecc" +- reg : Address and size for ECC block registers. +- altr,ecc-parent : phandle to parent Ethernet node. +- interrupts : Should be single bit error interrupt, then double bit error + interrupt, in this order. + Example: eccmgr: eccmgr@ffd06000 { @@ -108,4 +116,20 @@ Example: interrupts = <1 IRQ_TYPE_LEVEL_HIGH>, <33 IRQ_TYPE_LEVEL_HIGH> ; }; + + emac0-rx-ecc@ff8c0800 { + compatible = "altr,socfpga-eth-mac-ecc"; + reg = <0xff8c0800 0x400>; + altr,ecc-parent = <&gmac0>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>, + <36 IRQ_TYPE_LEVEL_HIGH>; + }; + + emac0-tx-ecc@ff8c0c00 { + compatible = "altr,socfpga-eth-mac-ecc"; + reg = <0xff8c0c00 0x400>; + altr,ecc-parent = <&gmac0>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>, + <37 IRQ_TYPE_LEVEL_HIGH>; + }; }; -- cgit v1.3-14-g43fede From 3680a4a97435496ad22cd0fc9f2ba51751cc4e36 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 9 Jun 2016 21:11:22 -0700 Subject: soc: qcom: Update properties for smem state referencing Update the property names to match device tree bindings, the correct values should be qcom,smem-states and qcom,smem-state-names. Also update the #qcom,smem-state-cells for consistency, before we merge any users of these properties. Signed-off-by: Bjorn Andersson Acked-by: Rob Herring Signed-off-by: Andy Gross --- Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt | 4 ++-- Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt | 4 ++-- drivers/soc/qcom/smem_state.c | 12 ++++++------ drivers/soc/qcom/smsm.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt index 5cc82b8353d8..af9ca37221ce 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.txt @@ -68,7 +68,7 @@ important. Value type: Definition: must be 2 - denoting the bit in the entry and IRQ flags -- #qcom,state-cells: +- #qcom,smem-state-cells: Usage: required for outgoing entries Value type: Definition: must be 1 - denoting the bit in the entry @@ -92,7 +92,7 @@ wcnss-smp2p { wcnss_smp2p_out: master-kernel { qcom,entry-name = "master-kernel"; - #qcom,state-cells = <1>; + #qcom,smem-state-cells = <1>; }; wcnss_smp2p_in: slave-kernel { diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt index a6634c70850d..2993b5a97dd6 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smsm.txt @@ -51,7 +51,7 @@ important. Definition: specifies the offset, in words, of the first bit for this entry -- #qcom,state-cells: +- #qcom,smem-state-cells: Usage: required for local entry Value type: Definition: must be 1 - denotes bit number @@ -91,7 +91,7 @@ smsm { apps_smsm: apps@0 { reg = <0>; - #qcom,state-cells = <1>; + #qcom,smem-state-cells = <1>; }; wcnss_smsm: wcnss@7 { diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c index 54261decb369..d5437ca76ed9 100644 --- a/drivers/soc/qcom/smem_state.c +++ b/drivers/soc/qcom/smem_state.c @@ -104,26 +104,26 @@ struct qcom_smem_state *qcom_smem_state_get(struct device *dev, if (con_id) { index = of_property_match_string(dev->of_node, - "qcom,state-names", + "qcom,smem-state-names", con_id); if (index < 0) { - dev_err(dev, "missing qcom,state-names\n"); + dev_err(dev, "missing qcom,smem-state-names\n"); return ERR_PTR(index); } } ret = of_parse_phandle_with_args(dev->of_node, - "qcom,state", - "#qcom,state-cells", + "qcom,smem-states", + "#qcom,smem-state-cells", index, &args); if (ret) { - dev_err(dev, "failed to parse qcom,state property\n"); + dev_err(dev, "failed to parse qcom,smem-states property\n"); return ERR_PTR(ret); } if (args.args_count != 1) { - dev_err(dev, "invalid #qcom,state-cells\n"); + dev_err(dev, "invalid #qcom,smem-state-cells\n"); return ERR_PTR(-EINVAL); } diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index 6b777af1bc19..d0337b2a71c8 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -495,7 +495,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) if (!smsm->hosts) return -ENOMEM; - local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,state-cells"); + local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,smem-state-cells"); if (!local_node) { dev_err(&pdev->dev, "no state entry\n"); return -EINVAL; -- cgit v1.3-14-g43fede From 7e1dc002c00b932dfefd9af05bdffa6f3986ad55 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 18 Apr 2016 13:26:16 -0400 Subject: tpm: Add documentation for the tpm_vtpm_proxy device driver Add documentation for the tpm_vtpm device driver that implements support for providing TPM functionality to Linux containers. Parts of this documentation were recycled from the Xen vTPM device driver documentation. Update the documentation for the ioctl numbers. Signed-off-by: Stefan Berger Reviewed-by: Jarkko Sakkinen CC: linux-kernel@vger.kernel.org CC: linux-doc@vger.kernel.org CC: linux-api@vger.kernel.org Tested-by: Jarkko Sakkinen Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- Documentation/ioctl/ioctl-number.txt | 1 + Documentation/tpm/tpm_vtpm_proxy.txt | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 Documentation/tpm/tpm_vtpm_proxy.txt (limited to 'Documentation') diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 9369d3b0f09a..56af5e43e9c0 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -303,6 +303,7 @@ Code Seq#(hex) Include File Comments 0xA0 all linux/sdp/sdp.h Industrial Device Project +0xA1 0 linux/vtpm_proxy.h TPM Emulator Proxy Driver 0xA2 00-0F arch/tile/include/asm/hardwall.h 0xA3 80-8F Port ACL in development: diff --git a/Documentation/tpm/tpm_vtpm_proxy.txt b/Documentation/tpm/tpm_vtpm_proxy.txt new file mode 100644 index 000000000000..30d19022f869 --- /dev/null +++ b/Documentation/tpm/tpm_vtpm_proxy.txt @@ -0,0 +1,71 @@ +Virtual TPM Proxy Driver for Linux Containers + +Authors: Stefan Berger (IBM) + +This document describes the virtual Trusted Platform Module (vTPM) +proxy device driver for Linux containers. + +INTRODUCTION +------------ + +The goal of this work is to provide TPM functionality to each Linux +container. This allows programs to interact with a TPM in a container +the same way they interact with a TPM on the physical system. Each +container gets its own unique, emulated, software TPM. + + +DESIGN +------ + +To make an emulated software TPM available to each container, the container +management stack needs to create a device pair consisting of a client TPM +character device /dev/tpmX (with X=0,1,2...) and a 'server side' file +descriptor. The former is moved into the container by creating a character +device with the appropriate major and minor numbers while the file descriptor +is passed to the TPM emulator. Software inside the container can then send +TPM commands using the character device and the emulator will receive the +commands via the file descriptor and use it for sending back responses. + +To support this, the virtual TPM proxy driver provides a device /dev/vtpmx +that is used to create device pairs using an ioctl. The ioctl takes as +an input flags for configuring the device. The flags for example indicate +whether TPM 1.2 or TPM 2 functionality is supported by the TPM emulator. +The result of the ioctl are the file descriptor for the 'server side' +as well as the major and minor numbers of the character device that was created. +Besides that the number of the TPM character device is return. If for +example /dev/tpm10 was created, the number (dev_num) 10 is returned. + +The following is the data structure of the TPM_PROXY_IOC_NEW_DEV ioctl: + +struct vtpm_proxy_new_dev { + __u32 flags; /* input */ + __u32 tpm_num; /* output */ + __u32 fd; /* output */ + __u32 major; /* output */ + __u32 minor; /* output */ +}; + +Note that if unsupported flags are passed to the device driver, the ioctl will +fail and errno will be set to EOPNOTSUPP. Similarly, if an unsupported ioctl is +called on the device driver, the ioctl will fail and errno will be set to +ENOTTY. + +See /usr/include/linux/vtpm_proxy.h for definitions related to the public interface +of this vTPM device driver. + +Once the device has been created, the driver will immediately try to talk +to the TPM. All commands from the driver can be read from the file descriptor +returned by the ioctl. The commands should be responded to immediately. + +Depending on the version of TPM the following commands will be sent by the +driver: + +- TPM 1.2: + - the driver will send a TPM_Startup command to the TPM emulator + - the driver will send commands to read the command durations and + interface timeouts from the TPM emulator +- TPM 2: + - the driver will send a TPM2_Startup command to the TPM emulator + +The TPM device /dev/tpmX will only appear if all of the relevant commands +were responded to properly. -- cgit v1.3-14-g43fede From 04bb2d8ee9a2eae73eab025739d3ce413feed3a8 Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Thu, 19 May 2016 00:35:50 +0200 Subject: devicetree: Add infineon to vendor-prefix.txt Add missing vendor to vendor-prefix.txt This commit is based on the initial work by Peter Huewe. Cc: devicetree@vger.kernel.org Signed-off-by: Christophe Ricard Acked-by: Rob Herring Acked-by: Jarkko Sakkinen Tested-by: Stefan Berger Reviewed-by: Stefan Berger Signed-off-by: Jarkko Sakkinen --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index a7440bcd67ff..f090d2e4c8ba 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -128,6 +128,7 @@ idt Integrated Device Technologies, Inc. ifi Ingenieurburo Fur Ic-Technologie (I/F/I) iom Iomega Corporation img Imagination Technologies Ltd. +infineon Infineon Technologies inforce Inforce Computing ingenic Ingenic Semiconductor innolux Innolux Corporation -- cgit v1.3-14-g43fede From 92eb0f73e3517b63337b7fccc2de150b4e6147ce Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Thu, 19 May 2016 00:35:51 +0200 Subject: devicetree: Add Trusted Computing Group to vendor-prefix.txt Add missing vendor to vendor-prefix.txt. Trusted Computing Group design common specifications for TPM (Trusted Platform Module) vendors. TCG designates a TPM answering to a public specification. This commit is based on the initial work by Peter Huewe. Cc: devicetree@vger.kernel.org Signed-off-by: Christophe Ricard Acked-by: Rob Herring Acked-by: Jarkko Sakkinen Tested-by: Stefan Berger Reviewed-by: Stefan Berger Signed-off-by: Jarkko Sakkinen --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index f090d2e4c8ba..fe78617d20e9 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -256,6 +256,7 @@ synology Synology, Inc. SUNW Sun Microsystems, Inc tbs TBS Technologies tcl Toby Churchill Ltd. +tcg Trusted Computing Group technologic Technologic Systems thine THine Electronics, Inc. ti Texas Instruments -- cgit v1.3-14-g43fede From 0edbfea537d10c0de5505d0413368aad71027663 Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Thu, 19 May 2016 00:35:53 +0200 Subject: tpm/tpm_tis_spi: Add support for spi phy Spi protocol standardized by the TCG is now supported by most of TPM vendors. It supports SPI Bit Protocol as describe in the TCG PTP specification (chapter 6.4.6 SPI Bit Protocol). Irq mode is not supported. This commit is based on the initial work by Peter Huewe. Signed-off-by: Peter Huewe Signed-off-by: Alexander Steffen Signed-off-by: Christophe Ricard Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Tested-by: Stefan Berger Reviewed-by: Stefan Berger Signed-off-by: Jarkko Sakkinen --- .../bindings/security/tpm/tpm_tis_spi.txt | 24 ++ drivers/char/tpm/Kconfig | 12 + drivers/char/tpm/Makefile | 1 + drivers/char/tpm/tpm_tis_spi.c | 272 +++++++++++++++++++++ 4 files changed, 309 insertions(+) create mode 100644 Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt create mode 100644 drivers/char/tpm/tpm_tis_spi.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt b/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt new file mode 100644 index 000000000000..85741cd468cc --- /dev/null +++ b/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt @@ -0,0 +1,24 @@ +Required properties: +- compatible: should be one of the following + "st,st33htpm-spi" + "infineon,slb9670" + "tcg,tpm_tis-spi" +- spi-max-frequency: Maximum SPI frequency (depends on TPMs). + +Optional SoC Specific Properties: +- pinctrl-names: Contains only one value - "default". +- pintctrl-0: Specifies the pin control groups used for this controller. + +Example (for ARM-based BeagleBoard xM with TPM_TIS on SPI4): + +&mcspi4 { + + status = "okay"; + + tpm_tis@0 { + + compatible = "tcg,tpm_tis-spi"; + + spi-max-frequency = <10000000>; + }; +}; diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 241ff4cc52a8..9faa0b1e7766 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -41,6 +41,18 @@ config TCG_TIS within Linux. To compile this driver as a module, choose M here; the module will be called tpm_tis. +config TCG_TIS_SPI + tristate "TPM Interface Specification 1.3 Interface / TPM 2.0 FIFO Interface - (SPI)" + depends on SPI + select TCG_TIS_CORE + ---help--- + If you have a TPM security chip which is connected to a regular, + non-tcg SPI master (i.e. most embedded platforms) that is compliant with the + TCG TIS 1.3 TPM specification (TPM1.2) or the TCG PTP FIFO + specification (TPM2.0) say Yes and it will be accessible from + within Linux. To compile this driver as a module, choose M here; + the module will be called tpm_tis_spi. + config TCG_TIS_I2C_ATMEL tristate "TPM Interface Specification 1.2 Interface (I2C - Atmel)" depends on I2C diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 662221f83018..a385fb8c17de 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -14,6 +14,7 @@ endif endif obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o obj-$(CONFIG_TCG_TIS) += tpm_tis.o +obj-$(CONFIG_TCG_TIS_SPI) += tpm_tis_spi.o obj-$(CONFIG_TCG_TIS_I2C_ATMEL) += tpm_i2c_atmel.o obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o obj-$(CONFIG_TCG_TIS_I2C_NUVOTON) += tpm_i2c_nuvoton.o diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c new file mode 100644 index 000000000000..dbaad9c681e3 --- /dev/null +++ b/drivers/char/tpm/tpm_tis_spi.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2015 Infineon Technologies AG + * Copyright (C) 2016 STMicroelectronics SAS + * + * Authors: + * Peter Huewe + * Christophe Ricard + * + * Maintained by: + * + * Device driver for TCG/TCPA TPM (trusted platform module). + * Specifications at www.trustedcomputinggroup.org + * + * This device driver implements the TPM interface as defined in + * the TCG TPM Interface Spec version 1.3, revision 27 via _raw/native + * SPI access_. + * + * It is based on the original tpm_tis device driver from Leendert van + * Dorn and Kyleen Hall and Jarko Sakkinnen. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "tpm.h" +#include "tpm_tis_core.h" + +#define MAX_SPI_FRAMESIZE 64 + +struct tpm_tis_spi_phy { + struct tpm_tis_data priv; + struct spi_device *spi_device; + + u8 tx_buf[MAX_SPI_FRAMESIZE + 4]; + u8 rx_buf[MAX_SPI_FRAMESIZE + 4]; +}; + +static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data) +{ + return container_of(data, struct tpm_tis_spi_phy, priv); +} + +static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, + u16 len, u8 *result) +{ + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); + int ret, i; + struct spi_message m; + struct spi_transfer spi_xfer = { + .tx_buf = phy->tx_buf, + .rx_buf = phy->rx_buf, + .len = 4, + }; + + if (len > MAX_SPI_FRAMESIZE) + return -ENOMEM; + + phy->tx_buf[0] = 0x80 | (len - 1); + phy->tx_buf[1] = 0xd4; + phy->tx_buf[2] = (addr >> 8) & 0xFF; + phy->tx_buf[3] = addr & 0xFF; + + spi_xfer.cs_change = 1; + spi_message_init(&m); + spi_message_add_tail(&spi_xfer, &m); + + spi_bus_lock(phy->spi_device->master); + ret = spi_sync_locked(phy->spi_device, &m); + if (ret < 0) + goto exit; + + memset(phy->tx_buf, 0, len); + + /* According to TCG PTP specification, if there is no TPM present at + * all, then the design has a weak pull-up on MISO. If a TPM is not + * present, a pull-up on MISO means that the SB controller sees a 1, + * and will latch in 0xFF on the read. + */ + for (i = 0; (phy->rx_buf[0] & 0x01) == 0 && i < TPM_RETRY; i++) { + spi_xfer.len = 1; + spi_message_init(&m); + spi_message_add_tail(&spi_xfer, &m); + ret = spi_sync_locked(phy->spi_device, &m); + if (ret < 0) + goto exit; + } + + spi_xfer.cs_change = 0; + spi_xfer.len = len; + spi_xfer.rx_buf = result; + + spi_message_init(&m); + spi_message_add_tail(&spi_xfer, &m); + ret = spi_sync_locked(phy->spi_device, &m); + +exit: + spi_bus_unlock(phy->spi_device->master); + return ret; +} + +static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr, + u16 len, u8 *value) +{ + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); + int ret, i; + struct spi_message m; + struct spi_transfer spi_xfer = { + .tx_buf = phy->tx_buf, + .rx_buf = phy->rx_buf, + .len = 4, + }; + + if (len > MAX_SPI_FRAMESIZE) + return -ENOMEM; + + phy->tx_buf[0] = len - 1; + phy->tx_buf[1] = 0xd4; + phy->tx_buf[2] = (addr >> 8) & 0xFF; + phy->tx_buf[3] = addr & 0xFF; + + spi_xfer.cs_change = 1; + spi_message_init(&m); + spi_message_add_tail(&spi_xfer, &m); + + spi_bus_lock(phy->spi_device->master); + ret = spi_sync_locked(phy->spi_device, &m); + if (ret < 0) + goto exit; + + memset(phy->tx_buf, 0, len); + + /* According to TCG PTP specification, if there is no TPM present at + * all, then the design has a weak pull-up on MISO. If a TPM is not + * present, a pull-up on MISO means that the SB controller sees a 1, + * and will latch in 0xFF on the read. + */ + for (i = 0; (phy->rx_buf[0] & 0x01) == 0 && i < TPM_RETRY; i++) { + spi_xfer.len = 1; + spi_message_init(&m); + spi_message_add_tail(&spi_xfer, &m); + ret = spi_sync_locked(phy->spi_device, &m); + if (ret < 0) + goto exit; + } + + spi_xfer.len = len; + spi_xfer.tx_buf = value; + spi_xfer.cs_change = 0; + spi_xfer.tx_buf = value; + spi_message_init(&m); + spi_message_add_tail(&spi_xfer, &m); + ret = spi_sync_locked(phy->spi_device, &m); + +exit: + spi_bus_unlock(phy->spi_device->master); + return ret; +} + +static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) +{ + int rc; + + rc = data->phy_ops->read_bytes(data, addr, sizeof(u16), (u8 *)result); + if (!rc) + *result = le16_to_cpu(*result); + return rc; +} + +static int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result) +{ + int rc; + + rc = data->phy_ops->read_bytes(data, addr, sizeof(u32), (u8 *)result); + if (!rc) + *result = le32_to_cpu(*result); + return rc; +} + +static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value) +{ + value = cpu_to_le32(value); + return data->phy_ops->write_bytes(data, addr, sizeof(u32), + (u8 *)&value); +} + +static const struct tpm_tis_phy_ops tpm_spi_phy_ops = { + .read_bytes = tpm_tis_spi_read_bytes, + .write_bytes = tpm_tis_spi_write_bytes, + .read16 = tpm_tis_spi_read16, + .read32 = tpm_tis_spi_read32, + .write32 = tpm_tis_spi_write32, +}; + +static int tpm_tis_spi_probe(struct spi_device *dev) +{ + struct tpm_tis_spi_phy *phy; + + phy = devm_kzalloc(&dev->dev, sizeof(struct tpm_tis_spi_phy), + GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->spi_device = dev; + + return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops, + NULL); +} + +static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); + +static int tpm_tis_spi_remove(struct spi_device *dev) +{ + struct tpm_chip *chip = spi_get_drvdata(dev); + + tpm_chip_unregister(chip); + tpm_tis_remove(chip); + return 0; +} + +static const struct spi_device_id tpm_tis_spi_id[] = { + {"tpm_tis_spi", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, tpm_tis_spi_id); + +static const struct of_device_id of_tis_spi_match[] = { + { .compatible = "st,st33htpm-spi", }, + { .compatible = "infineon,slb9670", }, + { .compatible = "tcg,tpm_tis-spi", }, + {} +}; +MODULE_DEVICE_TABLE(of, of_tis_spi_match); + +static const struct acpi_device_id acpi_tis_spi_match[] = { + {"SMO0768", 0}, + {} +}; +MODULE_DEVICE_TABLE(acpi, acpi_tis_spi_match); + +static struct spi_driver tpm_tis_spi_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "tpm_tis_spi", + .pm = &tpm_tis_pm, + .of_match_table = of_match_ptr(of_tis_spi_match), + .acpi_match_table = ACPI_PTR(acpi_tis_spi_match), + }, + .probe = tpm_tis_spi_probe, + .remove = tpm_tis_spi_remove, + .id_table = tpm_tis_spi_id, +}; +module_spi_driver(tpm_tis_spi_driver); + +MODULE_DESCRIPTION("TPM Driver for native SPI access"); +MODULE_LICENSE("GPL"); -- cgit v1.3-14-g43fede From 0c529b3fc6c66e618088aa3a998d760d1ad05272 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 3 Jun 2016 12:00:01 +0200 Subject: serial: sh-sci: Update DT binding documentation for GPIO modem lines Amend the DT bindings for the Renesas SCI driver to allow describing optional GPIO-controlled modem lines, which can be used where dedicated modem lines are not available. The property naming is dictated by the Generic Serial DT Bindings. Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Cc: devicetree@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 528c3b90f23c..997baeaa869b 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -76,6 +76,8 @@ Optional properties: - dmas: Must contain a list of two references to DMA specifiers, one for transmission, and one for reception. - dma-names: Must contain a list of two DMA names, "tx" and "rx". + - {cts,dsr,dcd,rng,rts,dtr}-gpios: Specify GPIOs for modem lines, cfr. the + generic serial DT bindings in serial.txt. Example: aliases { -- cgit v1.3-14-g43fede From b0405dc998e425bbb1f64488b6fda781b627056b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 3 Jun 2016 12:00:02 +0200 Subject: serial: sh-sci: Update DT binding documentation for dedicated RTS/CTS Some Renesas SCIF UARTs have dedicated lines for RTS/CTS hardware flow control. Whether these lines exist depends on SoC and UART instance inside the SoC. Whether these lines can be used for hardware flow control depends on board wiring. Amend the DT bindings with an optional property to indicate that RTS/CTS hardware flow control lines exist, and can be used as such, according to the Generic Serial DT Bindings. Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Cc: devicetree@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 997baeaa869b..7a0e15053db9 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -78,6 +78,8 @@ Optional properties: - dma-names: Must contain a list of two DMA names, "tx" and "rx". - {cts,dsr,dcd,rng,rts,dtr}-gpios: Specify GPIOs for modem lines, cfr. the generic serial DT bindings in serial.txt. + - uart-has-rtscts: Indicates dedicated lines for RTS/CTS hardware flow + control, cfr. the generic serial DT bindings in serial.txt. Example: aliases { -- cgit v1.3-14-g43fede From ac8305cd16ea2c35084ceb5cdf36f5a90c275c3a Mon Sep 17 00:00:00 2001 From: Hiromitsu Yamasaki Date: Thu, 12 May 2016 15:33:58 +0900 Subject: serial: sh-sci: Document SoC specific bindings for r8a7796 Signed-off-by: Hiromitsu Yamasaki Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 7a0e15053db9..1e4000d83aee 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -31,6 +31,8 @@ Required properties: - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. - "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART. - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. + - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. + - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, -- cgit v1.3-14-g43fede From 4ef03d328769eddbfeca1f1c958fdb181a69c341 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Tue, 31 May 2016 10:59:18 +0200 Subject: tty/serial/8250: use mctrl_gpio helpers This patch permits the usage for GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals. Signed-off-by: Yegor Yefremov Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/8250.txt | 19 ++++++++++++ drivers/tty/serial/8250/8250.h | 35 ++++++++++++++++++++++- drivers/tty/serial/8250/8250_core.c | 9 ++++++ drivers/tty/serial/8250/8250_omap.c | 31 +++++++++++--------- drivers/tty/serial/8250/8250_port.c | 7 ++++- drivers/tty/serial/8250/Kconfig | 1 + include/linux/serial_8250.h | 1 + 7 files changed, 88 insertions(+), 15 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index 936ab5b87324..f5561ac7e17e 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -42,6 +42,9 @@ Optional properties: - auto-flow-control: one way to enable automatic flow control support. The driver is allowed to detect support for the capability even without this property. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD + line respectively. It will use specified GPIO instead of the peripheral + function pin for the UART feature. If unsure, don't specify this property. Note: * fsl,ns16550: @@ -63,3 +66,19 @@ Example: interrupts = <10>; reg-shift = <2>; }; + +Example for OMAP UART using GPIO-based modem control signals: + + uart4: serial@49042000 { + compatible = "ti,omap3-uart"; + reg = <0x49042000 0x400>; + interrupts = <80>; + ti,hwmods = "uart4"; + clock-frequency = <48000000>; + cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; + rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; + dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + }; diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 1a16feac9a36..122e0e4029fe 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -15,6 +15,8 @@ #include #include +#include "../serial_mctrl_gpio.h" + struct uart_8250_dma { int (*tx_dma)(struct uart_8250_port *p); int (*rx_dma)(struct uart_8250_port *p); @@ -131,12 +133,43 @@ void serial8250_em485_destroy(struct uart_8250_port *p); static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) { + int mctrl_gpio = 0; + serial_out(up, UART_MCR, value); + + if (value & UART_MCR_RTS) + mctrl_gpio |= TIOCM_RTS; + if (value & UART_MCR_DTR) + mctrl_gpio |= TIOCM_DTR; + + mctrl_gpio_set(up->gpios, mctrl_gpio); } static inline int serial8250_in_MCR(struct uart_8250_port *up) { - return serial_in(up, UART_MCR); + int mctrl, mctrl_gpio = 0; + + mctrl = serial_in(up, UART_MCR); + + /* save current MCR values */ + if (mctrl & UART_MCR_RTS) + mctrl_gpio |= TIOCM_RTS; + if (mctrl & UART_MCR_DTR) + mctrl_gpio |= TIOCM_DTR; + + mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio); + + if (mctrl_gpio & TIOCM_RTS) + mctrl |= UART_MCR_RTS; + else + mctrl &= ~UART_MCR_RTS; + + if (mctrl_gpio & TIOCM_DTR) + mctrl |= UART_MCR_DTR; + else + mctrl &= ~UART_MCR_DTR; + + return mctrl; } #if defined(__alpha__) && !defined(CONFIG_PCI) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index dcf43f66404f..13ad5c3d2e68 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -974,6 +974,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) uart = serial8250_find_match_or_unused(&up->port); if (uart && uart->port.type != PORT_8250_CIR) { + struct mctrl_gpios *gpios; + if (uart->port.dev) uart_remove_one_port(&serial8250_reg, &uart->port); @@ -1011,6 +1013,13 @@ int serial8250_register_8250_port(struct uart_8250_port *up) if (up->port.flags & UPF_FIXED_TYPE) uart->port.type = up->port.type; + gpios = mctrl_gpio_init(&uart->port, 0); + if (IS_ERR(gpios)) { + if (PTR_ERR(gpios) != -ENOSYS) + return PTR_ERR(gpios); + } else + uart->gpios = gpios; + serial8250_set_defaults(uart); /* Possibly override default I/O functions. */ diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 61ad6c3b20a0..e14982f36a04 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -134,18 +134,21 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) serial8250_do_set_mctrl(port, mctrl); - /* - * Turn off autoRTS if RTS is lowered and restore autoRTS setting - * if RTS is raised - */ - lcr = serial_in(up, UART_LCR); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) - priv->efr |= UART_EFR_RTS; - else - priv->efr &= ~UART_EFR_RTS; - serial_out(up, UART_EFR, priv->efr); - serial_out(up, UART_LCR, lcr); + if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios, + UART_GPIO_RTS))) { + /* + * Turn off autoRTS if RTS is lowered and restore autoRTS + * setting if RTS is raised + */ + lcr = serial_in(up, UART_LCR); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) + priv->efr |= UART_EFR_RTS; + else + priv->efr &= ~UART_EFR_RTS; + serial_out(up, UART_EFR, priv->efr); + serial_out(up, UART_LCR, lcr); + } } /* @@ -446,7 +449,9 @@ static void omap_8250_set_termios(struct uart_port *port, priv->efr = 0; up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); - if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { + if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW + && IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios, + UART_GPIO_RTS))) { /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; priv->efr |= UART_EFR_CTS; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index bdfa659b9606..7481b95c6d84 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1618,6 +1618,8 @@ static void serial8250_disable_ms(struct uart_port *port) if (up->bugs & UART_BUG_NOMSR) return; + mctrl_gpio_disable_ms(up->gpios); + up->ier &= ~UART_IER_MSI; serial_port_out(port, UART_IER, up->ier); } @@ -1630,6 +1632,8 @@ static void serial8250_enable_ms(struct uart_port *port) if (up->bugs & UART_BUG_NOMSR) return; + mctrl_gpio_enable_ms(up->gpios); + up->ier |= UART_IER_MSI; serial8250_rpm_get(up); @@ -1913,7 +1917,8 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port) ret |= TIOCM_DSR; if (status & UART_MSR_CTS) ret |= TIOCM_CTS; - return ret; + + return mctrl_gpio_get(up->gpios, &ret); } EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index b5a0f2e76f08..b1c73dec7eda 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -6,6 +6,7 @@ config SERIAL_8250 tristate "8250/16550 and compatible serial support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB ---help--- This selects whether you want to include the driver for the standard serial ports. The standard answer is Y. People who might say N diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 48ec7651989b..923266cd294a 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -111,6 +111,7 @@ struct uart_8250_port { * if no_console_suspend */ unsigned char probe; + struct mctrl_gpios *gpios; #define UART_PROBE_RSA (1 << 0) /* -- cgit v1.3-14-g43fede From 65fe935dd2387a4faf15314c73f5e6d31ef0217e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 13 Jun 2016 15:10:02 -0700 Subject: x86/KASLR, x86/power: Remove x86 hibernation restrictions With the following fix: 70595b479ce1 ("x86/power/64: Fix crash whan the hibernation code passes control to the image kernel") ... there is no longer a problem with hibernation resuming a KASLR-booted kernel image, so remove the restriction. Signed-off-by: Kees Cook Cc: Andy Lutomirski Cc: Baoquan He Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Jonathan Corbet Cc: Len Brown Cc: Linus Torvalds Cc: Linux PM list Cc: Logan Gunthorpe Cc: Pavel Machek Cc: Peter Zijlstra Cc: Stephen Smalley Cc: Thomas Gleixner Cc: Yinghai Lu Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20160613221002.GA29719@www.outflux.net Signed-off-by: Ingo Molnar --- Documentation/kernel-parameters.txt | 10 ++++------ arch/x86/boot/compressed/kaslr.c | 7 ------- kernel/power/hibernate.c | 6 ------ 3 files changed, 4 insertions(+), 19 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..fa8c6d470ad2 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1803,12 +1803,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. js= [HW,JOY] Analog joystick See Documentation/input/joystick.txt. - kaslr/nokaslr [X86] - Enable/disable kernel and module base offset ASLR - (Address Space Layout Randomization) if built into - the kernel. When CONFIG_HIBERNATION is selected, - kASLR is disabled by default. When kASLR is enabled, - hibernation will be disabled. + nokaslr [KNL] + When CONFIG_RANDOMIZE_BASE is set, this disables + kernel and module base offset ASLR (Address Space + Layout Randomization). keepinitrd [HW,ARM] diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index cfeb0259ed81..dff42177cb0c 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -471,17 +471,10 @@ unsigned char *choose_random_location(unsigned long input, unsigned long choice = output; unsigned long random_addr; -#ifdef CONFIG_HIBERNATION - if (!cmdline_find_option_bool("kaslr")) { - warn("KASLR disabled: 'kaslr' not on cmdline (hibernation selected)."); - goto out; - } -#else if (cmdline_find_option_bool("nokaslr")) { warn("KASLR disabled: 'nokaslr' on cmdline."); goto out; } -#endif boot_params->hdr.loadflags |= KASLR_FLAG; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index fca9254280ee..9021387c6ff4 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -1154,11 +1154,6 @@ static int __init nohibernate_setup(char *str) return 1; } -static int __init kaslr_nohibernate_setup(char *str) -{ - return nohibernate_setup(str); -} - static int __init page_poison_nohibernate_setup(char *str) { #ifdef CONFIG_PAGE_POISONING_ZERO @@ -1182,5 +1177,4 @@ __setup("hibernate=", hibernate_setup); __setup("resumewait", resumewait_setup); __setup("resumedelay=", resumedelay_setup); __setup("nohibernate", nohibernate_setup); -__setup("kaslr", kaslr_nohibernate_setup); __setup("page_poison=", page_poison_nohibernate_setup); -- cgit v1.3-14-g43fede From c333dfe8dba7d3e47e97e1cee3c38123e19ae73c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 25 Jun 2016 22:52:11 -0700 Subject: regulator: qcom_spmi: Add support for S4 supply on pm8941 The S4 supply is sometimes called the boost regulator because it outputs 5V. Typically it's connected to the 5vs1 and 5vs2 switches for use in USB OTG and HDMI applications. Add support for this regulator which was mistakenly left out from the initial submission of this driver. Cc: Bjorn Andersson Fixes: e92a4047419c ("regulator: Add QCOM SPMI regulator driver") Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt | 4 ++-- drivers/regulator/qcom_spmi-regulator.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt index 46c6f3ed1a1c..3e827bb9a56d 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt @@ -113,8 +113,8 @@ pm8916: l14, l15, l16, l17, l18 pm8941: - s1, s2, s3, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, - l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, + s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, + l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, mvs1, mvs2 pm8994: diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 84cce21e98cd..fe09407b150b 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1496,6 +1496,7 @@ static const struct spmi_regulator_data pm8941_regulators[] = { { "s1", 0x1400, "vdd_s1", }, { "s2", 0x1700, "vdd_s2", }, { "s3", 0x1a00, "vdd_s3", }, + { "s4", 0xa000, }, { "l1", 0x4000, "vdd_l1_l3", }, { "l2", 0x4100, "vdd_l2_lvs_1_2_3", }, { "l3", 0x4200, "vdd_l1_l3", }, -- cgit v1.3-14-g43fede From 93bfe79b03365f410aa91caf04263173c008ecdf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 25 Jun 2016 22:52:12 -0700 Subject: regulator: qcom_spmi: Update mvs1/mvs2 switches on pm8941 The mvs1 and mvs2 switches are actually called 5vs1 and 5vs2 on some datasheets. Let's rename them to match the datasheets and also match the RPM based regulator driver which calls these by their 5vs names (see qcom_smd-regulator.c). There aren't any users of these regulators so far, so there aren't any concerns of DT ABI breakage here. While we're here making updates to the switches, also mandate usage of the OCP irq for these switches too. Cc: Bjorn Andersson Fixes: e92a4047419c ("regulator: Add QCOM SPMI regulator driver") Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt | 2 +- drivers/regulator/qcom_spmi-regulator.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt index 3e827bb9a56d..0fa3b0fac129 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt @@ -115,7 +115,7 @@ pm8916: pm8941: s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, - mvs1, mvs2 + 5vs1, 5vs2 pm8994: s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index fe09407b150b..43f8f20b82e9 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1524,8 +1524,8 @@ static const struct spmi_regulator_data pm8941_regulators[] = { { "lvs1", 0x8000, "vdd_l2_lvs_1_2_3", }, { "lvs2", 0x8100, "vdd_l2_lvs_1_2_3", }, { "lvs3", 0x8200, "vdd_l2_lvs_1_2_3", }, - { "mvs1", 0x8300, "vin_5vs", }, - { "mvs2", 0x8400, "vin_5vs", }, + { "5vs1", 0x8300, "vin_5vs", "ocp-5vs1", }, + { "5vs2", 0x8400, "vin_5vs", "ocp-5vs2", }, { } }; -- cgit v1.3-14-g43fede From e7ffd81233334b7755050523cb7e0456ae3d2e53 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Tue, 21 Jun 2016 20:33:28 +0800 Subject: net: stmmac: dwmac-rk: add rk3228-specific data Add constants and callback functions for the dwmac on rk3228/rk3229 socs. As can be seen, the base structure is the same, only registers and the bits in them moved slightly. Signed-off-by: Xing Zheng Reviewed-by: Heiko Stuebner Acked-by: Rob Herring Signed-off-by: David S. Miller --- .../devicetree/bindings/net/rockchip-dwmac.txt | 3 +- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 117 +++++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt index 93eac7ce1446..cccd945fc45b 100644 --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt @@ -3,7 +3,8 @@ Rockchip SoC RK3288 10/100/1000 Ethernet driver(GMAC) The device node has following properties. Required properties: - - compatible: Can be one of "rockchip,rk3288-gmac", "rockchip,rk3368-gmac" + - compatible: Can be one of "rockchip,rk3228-gmac", "rockchip,rk3288-gmac", + "rockchip,rk3368-gmac" - reg: addresses and length of the register sets for the device. - interrupts: Should contain the GMAC interrupts. - interrupt-names: Should contain the interrupt names "macirq". diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 63c2e4fda169..92105916ef40 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -73,6 +73,122 @@ struct rk_priv_data { #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) #define GRF_CLR_BIT(nr) (BIT(nr+16)) +#define RK3228_GRF_MAC_CON0 0x0900 +#define RK3228_GRF_MAC_CON1 0x0904 + +/* RK3228_GRF_MAC_CON0 */ +#define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) +#define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + +/* RK3228_GRF_MAC_CON1 */ +#define RK3228_GMAC_PHY_INTF_SEL_RGMII \ + (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) +#define RK3228_GMAC_PHY_INTF_SEL_RMII \ + (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) +#define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) +#define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) +#define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) +#define RK3228_GMAC_SPEED_100M GRF_BIT(2) +#define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) +#define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) +#define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) +#define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) +#define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) +#define RK3228_GMAC_RMII_MODE GRF_BIT(10) +#define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) +#define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) +#define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) +#define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) +#define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) + +static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_PHY_INTF_SEL_RGMII | + RK3228_GMAC_RMII_MODE_CLR | + RK3228_GMAC_RXCLK_DLY_ENABLE | + RK3228_GMAC_TXCLK_DLY_ENABLE); + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, + RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | + RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); +} + +static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_PHY_INTF_SEL_RMII | + RK3228_GMAC_RMII_MODE); + + /* set MAC to RMII mode */ + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); +} + +static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + if (speed == 10) + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_CLK_2_5M); + else if (speed == 100) + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_CLK_25M); + else if (speed == 1000) + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_CLK_125M); + else + dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); +} + +static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + if (speed == 10) + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_RMII_CLK_2_5M | + RK3228_GMAC_SPEED_10M); + else if (speed == 100) + regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, + RK3228_GMAC_RMII_CLK_25M | + RK3228_GMAC_SPEED_100M); + else + dev_err(dev, "unknown speed value for RMII! speed=%d", speed); +} + +static const struct rk_gmac_ops rk3228_ops = { + .set_to_rgmii = rk3228_set_to_rgmii, + .set_to_rmii = rk3228_set_to_rmii, + .set_rgmii_speed = rk3228_set_rgmii_speed, + .set_rmii_speed = rk3228_set_rmii_speed, +}; + #define RK3288_GRF_SOC_CON1 0x0248 #define RK3288_GRF_SOC_CON3 0x0250 @@ -642,6 +758,7 @@ static int rk_gmac_probe(struct platform_device *pdev) } static const struct of_device_id rk_gmac_dwmac_match[] = { + { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, { } -- cgit v1.3-14-g43fede From 86ab168614f7ddce0800456ab6da2cf40286a5b2 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 24 Jun 2016 19:16:53 +0200 Subject: leds: documentation: 'ide-disk' to 'disk-activity' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stephan Linz Cc: Joseph Jezak Cc: Jörg Sommer Acked-by: Mark Rutland Signed-off-by: Jacek Anaszewski --- Documentation/devicetree/bindings/leds/common.txt | 4 +++- Documentation/devicetree/bindings/leds/leds-gpio.txt | 4 ++-- Documentation/laptops/asus-laptop.txt | 2 +- Documentation/leds/leds-class.txt | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/leds/common.txt b/Documentation/devicetree/bindings/leds/common.txt index af10678ea2f6..93ef6e6e43b5 100644 --- a/Documentation/devicetree/bindings/leds/common.txt +++ b/Documentation/devicetree/bindings/leds/common.txt @@ -26,7 +26,9 @@ Optional properties for child nodes: "default-on" - LED will turn on (but for leds-gpio see "default-state" property in Documentation/devicetree/bindings/gpio/led.txt) "heartbeat" - LED "double" flashes at a load average based rate - "ide-disk" - LED indicates disk activity + "disk-activity" - LED indicates disk activity + "ide-disk" - LED indicates IDE disk activity (deprecated), + in new implementations use "disk-activity" "timer" - LED flashes at a fixed, configurable rate - led-max-microamp : Maximum LED supply current in microamperes. This property diff --git a/Documentation/devicetree/bindings/leds/leds-gpio.txt b/Documentation/devicetree/bindings/leds/leds-gpio.txt index cbbeb1850910..5b1b43a64265 100644 --- a/Documentation/devicetree/bindings/leds/leds-gpio.txt +++ b/Documentation/devicetree/bindings/leds/leds-gpio.txt @@ -33,9 +33,9 @@ Examples: leds { compatible = "gpio-leds"; hdd { - label = "IDE Activity"; + label = "Disk Activity"; gpios = <&mcu_pio 0 GPIO_ACTIVE_LOW>; - linux,default-trigger = "ide-disk"; + linux,default-trigger = "disk-activity"; }; fault { diff --git a/Documentation/laptops/asus-laptop.txt b/Documentation/laptops/asus-laptop.txt index 79a1bc675a8d..5f2858712aa0 100644 --- a/Documentation/laptops/asus-laptop.txt +++ b/Documentation/laptops/asus-laptop.txt @@ -72,7 +72,7 @@ LEDs echo 1 > /sys/class/leds/asus::mail/brightness will switch the mail LED on. You can also know if they are on/off by reading their content and use - kernel triggers like ide-disk or heartbeat. + kernel triggers like disk-activity or heartbeat. Backlight --------- diff --git a/Documentation/leds/leds-class.txt b/Documentation/leds/leds-class.txt index 44f5e6bccd97..f1f7ec9f5cc5 100644 --- a/Documentation/leds/leds-class.txt +++ b/Documentation/leds/leds-class.txt @@ -11,7 +11,7 @@ brightness support so will just be turned on for non-zero brightness settings. The class also introduces the optional concept of an LED trigger. A trigger is a kernel based source of led events. Triggers can either be simple or complex. A simple trigger isn't configurable and is designed to slot into -existing subsystems with minimal additional code. Examples are the ide-disk, +existing subsystems with minimal additional code. Examples are the disk-activity, nand-disk and sharpsl-charge triggers. With led triggers disabled, the code optimises away. -- cgit v1.3-14-g43fede From ab1778752921800468057d996f9a3bb9426870c3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 22 Jun 2016 17:27:01 -0700 Subject: Documentation: devicetree: bindings: Add BCM5301x binding Document the binding used by the Broadcom BCM5301x (Northstar) SoC random number generator. Signed-off-by: Florian Fainelli Signed-off-by: Herbert Xu --- Documentation/devicetree/bindings/rng/brcm,bcm2835.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt index aa304d412058..26542690b578 100644 --- a/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt +++ b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt @@ -2,7 +2,8 @@ BCM2835 Random number generator Required properties: -- compatible : should be "brcm,bcm2835-rng" or "brcm,bcm-nsp-rng" +- compatible : should be "brcm,bcm2835-rng" or "brcm,bcm-nsp-rng" or + "brcm,bcm5301x-rng" - reg : Specifies base physical address and size of the registers. Example: -- cgit v1.3-14-g43fede From 3b76df4b1eea5395e0fd44402720c9053d8ca305 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 20 Jun 2016 14:28:42 -0700 Subject: dt-binding: remoteproc: Introduce Hexagon loader binding This document defines the binding for a component that loads firmware and control the life cycle of a self-authenticating Qualcomm Hexagon core. Acked-by: Rob Herring Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/remoteproc/qcom,q6v5.txt | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt new file mode 100644 index 000000000000..57cb49ec55ca --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt @@ -0,0 +1,137 @@ +Qualcomm Hexagon Peripheral Image Loader + +This document defines the binding for a component that loads and boots firmware +on the Qualcomm Hexagon core. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,q6v5-pil" + +- reg: + Usage: required + Value type: + Definition: must specify the base address and size of the qdsp6 and + rmb register blocks + +- reg-names: + Usage: required + Value type: + Definition: must be "q6dsp" and "rmb" + +- interrupts-extended: + Usage: required + Value type: + Definition: must list the watchdog, fatal IRQs ready, handover and + stop-ack IRQs + +- interrupt-names: + Usage: required + Value type: + Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack" + +- clocks: + Usage: required + Value type: + Definition: reference to the iface, bus and mem clocks to be held on + behalf of the booting of the Hexagon core + +- clock-names: + Usage: required + Value type: + Definition: must be "iface", "bus", "mem" + +- resets: + Usage: required + Value type: + Definition: reference to the reset-controller for the modem sub-system + +- reset-names: + Usage: required + Value type: + Definition: must be "mss_restart" + +- cx-supply: +- mss-supply: +- mx-supply: +- pll-supply: + Usage: required + Value type: + Definition: reference to the regulators to be held on behalf of the + booting of the Hexagon core + +- qcom,smem-states: + Usage: required + Value type: + Definition: reference to the smem state for requesting the Hexagon to + shut down + +- qcom,smem-state-names: + Usage: required + Value type: + Definition: must be "stop" + +- qcom,halt-regs: + Usage: required + Value type: + Definition: a phandle reference to a syscon representing TCSR followed + by the three offsets within syscon for q6, modem and nc + halt registers. + += SUBNODES: +The Hexagon node must contain two subnodes, named "mba" and "mpss" representing +the memory regions used by the Hexagon firmware. Each sub-node must contain: + +- memory-region: + Usage: required + Value type: + Definition: reference to the reserved-memory for the region + += EXAMPLE +The following example describes the resources needed to boot control the +Hexagon, as it is found on MSM8974 boards. + + modem-rproc@fc880000 { + compatible = "qcom,q6v5-pil"; + reg = <0xfc880000 0x100>, + <0xfc820000 0x020>; + reg-names = "qdsp6", "rmb"; + + interrupts-extended = <&intc 0 24 1>, + <&modem_smp2p_in 0 0>, + <&modem_smp2p_in 1 0>, + <&modem_smp2p_in 2 0>, + <&modem_smp2p_in 3 0>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + clocks = <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>, + <&gcc GCC_MSS_CFG_AHB_CLK>, + <&gcc GCC_BOOT_ROM_AHB_CLK>; + clock-names = "iface", "bus", "mem"; + + qcom,halt-regs = <&tcsr_mutex_block 0x1180 0x1200 0x1280>; + + resets = <&gcc GCC_MSS_RESTART>; + reset-names = "mss_restart"; + + cx-supply = <&pm8841_s2>; + mss-supply = <&pm8841_s3>; + mx-supply = <&pm8841_s1>; + pll-supply = <&pm8941_l12>; + + qcom,smem-states = <&modem_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + mba { + memory-region = <&mba_region>; + }; + + mpss { + memory-region = <&mpss_region>; + }; + }; -- cgit v1.3-14-g43fede From 7c2438c61c2ad20ce995492baa702b7485035683 Mon Sep 17 00:00:00 2001 From: Paul Handrigan Date: Thu, 23 Jun 2016 13:30:02 -0500 Subject: ASoC: cs35l33: Add device tree bindings file for cs35l33 Add device tree bindings file for the cs35l33 8V boosted class D amplifier. Signed-off-by: Paul Handrigan Acked-by: Rob Herring Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/cs35l33.txt | 126 +++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/cs35l33.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/cs35l33.txt b/Documentation/devicetree/bindings/sound/cs35l33.txt new file mode 100644 index 000000000000..acfb47525b49 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs35l33.txt @@ -0,0 +1,126 @@ +CS35L33 Speaker Amplifier + +Required properties: + + - compatible : "cirrus,cs35l33" + + - reg : the I2C address of the device for I2C + + - VA-supply, VP-supply : power supplies for the device, + as covered in + Documentation/devicetree/bindings/regulator/regulator.txt. + +Optional properties: + + - reset-gpios : gpio used to reset the amplifier + + - interrupt-parent : Specifies the phandle of the interrupt controller to + which the IRQs from CS35L33 are delivered to. + - interrupts : IRQ line info CS35L33. + (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + for further information relating to interrupt properties) + + - cirrus,boost-ctl : Booster voltage use to supply the amp. If the value is + 0, then VBST = VP. If greater than 0, the boost voltage will be 3300mV with + a value of 1 and will increase at a step size of 100mV until a maximum of + 8000mV. + + - cirrus,ramp-rate : On power up, it affects the time from when the power + up sequence begins to the time the audio reaches a full-scale output. + On power down, it affects the time from when the power-down sequence + begins to when the amplifier disables the PWM outputs. If this property + is not set then soft ramping will be disabled and ramp time would be + 20ms. If this property is set to 0,1,2,3 then ramp times would be 40ms, + 60ms,100ms,175ms respectively for 48KHz sample rate. + + - cirrus,boost-ipk : The maximum current allowed for the boost converter. + The range starts at 1850000uA and goes to a maximum of 3600000uA + with a step size of 15625uA. The default is 2500000uA. + + - cirrus,imon-adc-scale : Configures the scaling of data bits from the IMON + ADC data word. This property can be set as a value of 0 for bits 15 down + to 0, 6 for 21 down to 6, 7, for 22 down to 7, 8 for 23 down to 8. + + +Optional H/G Algorithm sub-node: + +The cs35l33 node can have a single "cirrus,hg-algo" sub-node that will enable +the internal H/G Algorithm. + + - cirrus,hg-algo : Sub-node for internal Class H/G algorithm that + controls the amplifier supplies. + +Optional properties for the "cirrus,hg-algo" sub-node: + + - cirrus,mem-depth : Memory depth for the Class H/G algorithm measured in + LRCLK cycles. If this property is set to 0, 1, 2, or 3 then the memory + depths will be 1, 4, 8, 16 LRCLK cycles. The default is 16 LRCLK cycles. + + cirrus,release-rate : The number of consecutive LRCLK periods before + allowing release condition tracking updates. The number of LRCLK periods + start at 3 to a maximum of 255. + + - cirrus,ldo-thld : Configures the signal threshold at which the PWM output + stage enters LDO operation. Starts as a default value of 50mV for a value + of 1 and increases with a step size of 50mV to a maximum of 750mV (value of + 0xF). + + - cirrus,ldo-path-disable : This is a boolean property. If present, the H/G + algorithm uses the max detection path. If not present, the LDO + detection path is used. + + - cirrus,ldo-entry-delay : The LDO entry delay in milliseconds before the H/G + algorithm switches to the LDO voltage. This property can be set to values + from 0 to 7 for delays of 5ms, 10ms, 50ms, 100ms, 200ms, 500ms, 1000ms. + The default is 100ms. + + - cirrus,vp-hg-auto : This is a boolean property. When set, class H/G VPhg + automatic updating is enabled. + + - cirrus,vp-hg : Class H/G algorithm VPhg. Controls the H/G algorithm's + reference to the VP voltage for when to start generating a boosted VBST. + The reference voltage starts at 3000mV with a value of 0x3 and is increased + by 100mV per step to a maximum of 5500mV. + + - cirrus,vp-hg-rate : The rate (number of LRCLK periods) at which the VPhg is + allowed to increase to a higher voltage when using VPhg automatic + tracking. This property can be set to values from 0 to 3 with rates of 128 + periods, 2048 periods, 32768 periods, and 524288 periods. + The default is 32768 periods. + + - cirrus,vp-hg-va : VA calculation reference for automatic VPhg tracking + using VPMON. This property can be set to values from 0 to 6 starting at + 1800mV with a step size of 50mV up to a maximum value of 1750mV. + Default is 1800mV. + +Example: + +cs35l33: cs35l33@40 { + compatible = "cirrus,cs35l33"; + reg = <0x40>; + + VA-supply = <&ldo5_reg>; + VP-supply = <&ldo5_reg>; + + interrupt-parent = <&gpio8>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + + reset-gpios = <&cs47l91 34 0>; + + cirrus,ramp-rate = <0x0>; + cirrus,boost-ctl = <0x30>; /* VBST = 8000mV */ + cirrus,boost-ipk = <0xE0>; /* 3600mA */ + cirrus,imon-adc-scale = <0> /* Bits 15 down to 0 */ + + cirrus,hg-algo { + cirrus,mem-depth = <0x3>; + cirrus,release-rate = <0x3>; + cirrus,ldo-thld = <0x1>; + cirrus,ldo-path-disable = <0x0>; + cirrus,ldo-entry-delay=<0x4>; + cirrus,vp-hg-auto; + cirrus,vp-hg=<0xF>; + cirrus,vp-hg-rate=<0x2>; + cirrus,vp-hg-va=<0x0>; + }; +}; -- cgit v1.3-14-g43fede From 241eff3c198492b2d63e75723b774f2836fee8a3 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Wed, 22 Jun 2016 11:16:53 +0800 Subject: ARM: dts: rockchip: add support rk3229 evb board Initial release for rk3229 evb board, and turn the GMAC on. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/arm/rockchip.txt | 3 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/rk3229-evb.dts | 90 ++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 arch/arm/boot/dts/rk3229-evb.dts (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index 715d960d5eea..666864517069 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -107,6 +107,9 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "rockchip,rk3228-evb", "rockchip,rk3228"; +- Rockchip RK3229 Evaluation board: + - compatible = "rockchip,rk3229-evb", "rockchip,rk3229"; + - Rockchip RK3399 evb: Required root node properties: - compatible = "rockchip,rk3399-evb", "rockchip,rk3399"; diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 06b6c2d695bf..5e0833f72ea3 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -602,6 +602,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3066a-rayeager.dtb \ rk3188-radxarock.dtb \ rk3228-evb.dtb \ + rk3229-evb.dtb \ rk3288-evb-act8846.dtb \ rk3288-evb-rk808.dtb \ rk3288-firefly-beta.dtb \ diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts new file mode 100644 index 000000000000..b6a12035a6bb --- /dev/null +++ b/arch/arm/boot/dts/rk3229-evb.dts @@ -0,0 +1,90 @@ +/* + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "rk322x.dtsi" + +/ { + model = "Rockchip RK3229 Evaluation board"; + compatible = "rockchip,rk3229-evb", "rockchip,rk3229"; + + memory { + device_type = "memory"; + reg = <0x60000000 0x40000000>; + }; + + ext_gmac: ext_gmac { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "ext_gmac"; + #clock-cells = <0>; + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + enable-active-high; + regulator-name = "vcc_phy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&gmac { + assigned-clocks = <&cru SCLK_MAC_EXTCLK>, <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>, <&cru SCLK_MAC_EXTCLK>; + clock_in_out = "input"; + phy-supply = <&vcc_phy>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio2 24 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 1000000>; + tx_delay = <0x30>; + rx_delay = <0x10>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; -- cgit v1.3-14-g43fede From 67626cc1a0f7bd6700b6f2f547244382247f5bb3 Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Mon, 27 Jun 2016 10:27:18 +0200 Subject: iio: ad5755: Add DT binding documentation Signed-off-by: Sean Nyekjaer Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/dac/ad5755.txt | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/dac/ad5755.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/dac/ad5755.txt b/Documentation/devicetree/bindings/iio/dac/ad5755.txt new file mode 100644 index 000000000000..f0bbd7e1029b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/ad5755.txt @@ -0,0 +1,124 @@ +* Analog Device AD5755 IIO Multi-Channel DAC Linux Driver + +Required properties: + - compatible: Has to contain one of the following: + adi,ad5755 + adi,ad5755-1 + adi,ad5757 + adi,ad5735 + adi,ad5737 + + - reg: spi chip select number for the device + - spi-cpha or spi-cpol: is the only modes that is supported + +Recommended properties: + - spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Optional properties: +See include/dt-bindings/iio/ad5755.h + - adi,ext-dc-dc-compenstation-resistor: boolean set if the hardware have an + external resistor and thereby bypasses + the internal compensation resistor. + - adi,dc-dc-phase: + Valid values for DC DC Phase control is: + 0: All dc-to-dc converters clock on the same edge. + 1: Channel A and Channel B clock on the same edge, + Channel C and Channel D clock on opposite edges. + 2: Channel A and Channel C clock on the same edge, + Channel B and Channel D clock on opposite edges. + 3: Channel A, Channel B, Channel C, and Channel D + clock 90 degrees out of phase from each other. + - adi,dc-dc-freq-hz: + Valid values for DC DC frequency is [Hz]: + 250000 + 410000 + 650000 + - adi,dc-dc-max-microvolt: + Valid values for the maximum allowed Vboost voltage supplied by + the dc-to-dc converter is: + 23000000 + 24500000 + 27000000 + 29500000 + +Optional for every channel: + - adi,mode: + Valid values for DAC modes is: + 0: 0 V to 5 V voltage range. + 1: 0 V to 10 V voltage range. + 2: Plus minus 5 V voltage range. + 3: Plus minus 10 V voltage range. + 4: 4 mA to 20 mA current range. + 5: 0 mA to 20 mA current range. + 6: 0 mA to 24 mA current range. + - adi,ext-current-sense-resistor: boolean set if the hardware a external + current sense resistor. + - adi,enable-voltage-overrange: boolean enable voltage overrange + - adi,slew: Array of slewrate settings should contain 3 fields: + 1: Should be either 0 or 1 in order to enable or disable slewrate. + 2: Slew rate settings: + Valid values for the slew rate update frequency: + 64000 + 32000 + 16000 + 8000 + 4000 + 2000 + 1000 + 500 + 250 + 125 + 64 + 32 + 16 + 8 + 4 + 0 + 3: Slew step size: + Valid values for the step size LSBs: + 1 + 2 + 4 + 16 + 32 + 64 + 128 + 256 + +Example: +dac@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "adi,ad5755"; + reg = <0>; + spi-max-frequency = <1000000>; + spi-cpha; + adi,dc-dc-phase = <0>; + adi,dc-dc-freq-hz = <410000>; + adi,dc-dc-max-microvolt = <23000000>; + channel@0 { + reg = <0>; + adi,mode = <4>; + adi,ext-current-sense-resistor; + adi,slew = <0 64000 1>; + }; + channel@1 { + reg = <1>; + adi,mode = <4>; + adi,ext-current-sense-resistor; + adi,slew = <0 64000 1>; + }; + channel@2 { + reg = <2>; + adi,mode = <4>; + adi,ext-current-sense-resistor; + adi,slew = <0 64000 1>; + }; + channel@3 { + reg = <3>; + adi,mode = <4>; + adi,ext-current-sense-resistor; + adi,slew = <0 64000 1>; + }; +}; -- cgit v1.3-14-g43fede From b6757042200f8c876be99213712f4a101334e203 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 13:41:00 +0200 Subject: hwmon: (abituguru) Fix typos in documentation Signed-off-by: Andrea Gelmini [groeck: Updated subject] Signed-off-by: Guenter Roeck --- Documentation/hwmon/abituguru | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru index f1d4fe4c366c..44013d23b3f0 100644 --- a/Documentation/hwmon/abituguru +++ b/Documentation/hwmon/abituguru @@ -24,7 +24,7 @@ Supported chips: AW9D-MAX) (2) 1) For revisions 2 and 3 uGuru's the driver can autodetect the sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's - this doesnot always work. For these uGuru's the autodection can + this does not always work. For these uGuru's the autodetection can be overridden with the bank1_types module param. For all 3 known revison 1 motherboards the correct use of this param is: bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1 -- cgit v1.3-14-g43fede From 76b5808e8cb9d8be214a1bbf613e19b6e3ebb3fb Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 21 May 2016 13:41:07 +0200 Subject: hwmon: (max1668) Fix typo in documentation Signed-off-by: Andrea Gelmini [groeck: Updated subject] Signed-off-by: Guenter Roeck --- Documentation/hwmon/max1668 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/max1668 b/Documentation/hwmon/max1668 index 0616ed9758df..8f9d570dbfec 100644 --- a/Documentation/hwmon/max1668 +++ b/Documentation/hwmon/max1668 @@ -17,7 +17,7 @@ This driver implements support for the Maxim MAX1668, MAX1805 and MAX1989 chips. The three devices are very similar, but the MAX1805 has a reduced feature -set; only two remote temperature inputs vs the four avaible on the other +set; only two remote temperature inputs vs the four available on the other two ICs. The driver is able to distinguish between the devices and creates sysfs -- cgit v1.3-14-g43fede From 7c84f7f80d6fcea36246b793d06c3555ca53ddcd Mon Sep 17 00:00:00 2001 From: David Frey Date: Thu, 2 Jun 2016 09:59:11 +0200 Subject: hwmon: add support for Sensirion SHT3x sensors This driver implements support for the Sensirion SHT3x-DIS chip, a humidity and temperature sensor. Temperature is measured in degrees celsius, relative humidity is expressed as a percentage. In the sysfs interface, all values are scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500. Signed-off-by: Pascal Sachs [groeck: Fixed 'Variable length array is used' gcc warning] Signed-off-by: Guenter Roeck --- Documentation/hwmon/sht3x | 72 ++++ drivers/hwmon/Kconfig | 11 + drivers/hwmon/Makefile | 1 + drivers/hwmon/sht3x.c | 725 ++++++++++++++++++++++++++++++++++++ include/linux/platform_data/sht3x.h | 25 ++ 5 files changed, 834 insertions(+) create mode 100644 Documentation/hwmon/sht3x create mode 100644 drivers/hwmon/sht3x.c create mode 100644 include/linux/platform_data/sht3x.h (limited to 'Documentation') diff --git a/Documentation/hwmon/sht3x b/Documentation/hwmon/sht3x new file mode 100644 index 000000000000..f5aa633ed383 --- /dev/null +++ b/Documentation/hwmon/sht3x @@ -0,0 +1,72 @@ +Kernel driver sht3x +=================== + +Supported chips: + * Sensirion SHT3x-DIS + Prefix: 'sht3x' + Addresses scanned: none + Datasheet: http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_Datasheet_SHT3x_DIS.pdf + +Author: + David Frey + Pascal Sachs + +Description +----------- + +This driver implements support for the Sensirion SHT3x-DIS chip, a humidity +and temperature sensor. Temperature is measured in degrees celsius, relative +humidity is expressed as a percentage. In the sysfs interface, all values are +scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500. + +The device communicates with the I2C protocol. Sensors can have the I2C +addresses 0x44 or 0x45, depending on the wiring. See +Documentation/i2c/instantiating-devices for methods to instantiate the device. + +There are two options configurable by means of sht3x_platform_data: +1. blocking (pull the I2C clock line down while performing the measurement) or + non-blocking mode. Blocking mode will guarantee the fastest result but + the I2C bus will be busy during that time. By default, non-blocking mode + is used. Make sure clock-stretching works properly on your device if you + want to use blocking mode. +2. high or low accuracy. High accuracy is used by default and using it is + strongly recommended. + +The sht3x sensor supports a single shot mode as well as 5 periodic measure +modes, which can be controlled with the update_interval sysfs interface. +The allowed update_interval in milliseconds are as follows: + * 0 single shot mode + * 2000 0.5 Hz periodic measurement + * 1000 1 Hz periodic measurement + * 500 2 Hz periodic measurement + * 250 4 Hz periodic measurement + * 100 10 Hz periodic measurement + +In the periodic measure mode, the sensor automatically triggers a measurement +with the configured update interval on the chip. When a temperature or humidity +reading exceeds the configured limits, the alert attribute is set to 1 and +the alert pin on the sensor is set to high. +When the temperature and humidity readings move back between the hysteresis +values, the alert bit is set to 0 and the alert pin on the sensor is set to +low. + +sysfs-Interface +--------------- + +temp1_input: temperature input +humidity1_input: humidity input +temp1_max: temperature max value +temp1_max_hyst: temperature hysteresis value for max limit +humidity1_max: humidity max value +humidity1_max_hyst: humidity hysteresis value for max limit +temp1_min: temperature min value +temp1_min_hyst: temperature hysteresis value for min limit +humidity1_min: humidity min value +humidity1_min_hyst: humidity hysteresis value for min limit +temp1_alarm: alarm flag is set to 1 if the temperature is outside the + configured limits. Alarm only works in periodic measure mode +humidity1_alarm: alarm flag is set to 1 if the humidity is outside the + configured limits. Alarm only works in periodic measure mode +update_interval: update interval, 0 for single shot, interval in msec + for periodic measurement. If the interval is not supported + by the sensor, the next faster interval is chosen diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ff940075bb90..e0be99a4615c 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1265,6 +1265,17 @@ config SENSORS_SHT21 This driver can also be built as a module. If so, the module will be called sht21. +config SENSORS_SHT3x + tristate "Sensiron humidity and temperature sensors. SHT3x and compat." + depends on I2C + select CRC8 + help + If you say yes here you get support for the Sensiron SHT30 and SHT31 + humidity and temperature sensors. + + This driver can also be built as a module. If so, the module + will be called sht3x. + config SENSORS_SHTC1 tristate "Sensiron humidity and temperature sensors. SHTC1 and compat." depends on I2C diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 2ef5b7c4c54f..406b18b995b3 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -138,6 +138,7 @@ obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o obj-$(CONFIG_SENSORS_SHT15) += sht15.o obj-$(CONFIG_SENSORS_SHT21) += sht21.o +obj-$(CONFIG_SENSORS_SHT3x) += sht3x.o obj-$(CONFIG_SENSORS_SHTC1) += shtc1.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SMM665) += smm665.o diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c new file mode 100644 index 000000000000..707a3f85385b --- /dev/null +++ b/drivers/hwmon/sht3x.c @@ -0,0 +1,725 @@ +/* Sensirion SHT3x-DIS humidity and temperature sensor driver. + * The SHT3x comes in many different versions, this driver is for the + * I2C version only. + * + * Copyright (C) 2016 Sensirion AG, Switzerland + * Author: David Frey + * Author: Pascal Sachs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* commands (high precision mode) */ +static const unsigned char sht3x_cmd_measure_blocking_hpm[] = { 0x2c, 0x06 }; +static const unsigned char sht3x_cmd_measure_nonblocking_hpm[] = { 0x24, 0x00 }; + +/* commands (low power mode) */ +static const unsigned char sht3x_cmd_measure_blocking_lpm[] = { 0x2c, 0x10 }; +static const unsigned char sht3x_cmd_measure_nonblocking_lpm[] = { 0x24, 0x16 }; + +/* commands for periodic mode */ +static const unsigned char sht3x_cmd_measure_periodic_mode[] = { 0xe0, 0x00 }; +static const unsigned char sht3x_cmd_break[] = { 0x30, 0x93 }; + +/* other commands */ +static const unsigned char sht3x_cmd_read_status_reg[] = { 0xf3, 0x2d }; +static const unsigned char sht3x_cmd_clear_status_reg[] = { 0x30, 0x41 }; + +/* delays for non-blocking i2c commands, both in us */ +#define SHT3X_NONBLOCKING_WAIT_TIME_HPM 15000 +#define SHT3X_NONBLOCKING_WAIT_TIME_LPM 4000 + +#define SHT3X_WORD_LEN 2 +#define SHT3X_CMD_LENGTH 2 +#define SHT3X_CRC8_LEN 1 +#define SHT3X_RESPONSE_LENGTH 6 +#define SHT3X_CRC8_POLYNOMIAL 0x31 +#define SHT3X_CRC8_INIT 0xFF +#define SHT3X_MIN_TEMPERATURE -45000 +#define SHT3X_MAX_TEMPERATURE 130000 +#define SHT3X_MIN_HUMIDITY 0 +#define SHT3X_MAX_HUMIDITY 100000 + +enum sht3x_chips { + sht3x, + sts3x, +}; + +enum sht3x_limits { + limit_max = 0, + limit_max_hyst, + limit_min, + limit_min_hyst, +}; + +DECLARE_CRC8_TABLE(sht3x_crc8_table); + +/* periodic measure commands (high precision mode) */ +static const char periodic_measure_commands_hpm[][SHT3X_CMD_LENGTH] = { + /* 0.5 measurements per second */ + {0x20, 0x32}, + /* 1 measurements per second */ + {0x21, 0x30}, + /* 2 measurements per second */ + {0x22, 0x36}, + /* 4 measurements per second */ + {0x23, 0x34}, + /* 10 measurements per second */ + {0x27, 0x37}, +}; + +/* periodic measure commands (low power mode) */ +static const char periodic_measure_commands_lpm[][SHT3X_CMD_LENGTH] = { + /* 0.5 measurements per second */ + {0x20, 0x2f}, + /* 1 measurements per second */ + {0x21, 0x2d}, + /* 2 measurements per second */ + {0x22, 0x2b}, + /* 4 measurements per second */ + {0x23, 0x29}, + /* 10 measurements per second */ + {0x27, 0x2a}, +}; + +struct sht3x_limit_commands { + const char read_command[SHT3X_CMD_LENGTH]; + const char write_command[SHT3X_CMD_LENGTH]; +}; + +static const struct sht3x_limit_commands limit_commands[] = { + /* temp1_max, humidity1_max */ + [limit_max] = { {0xe1, 0x1f}, {0x61, 0x1d} }, + /* temp_1_max_hyst, humidity1_max_hyst */ + [limit_max_hyst] = { {0xe1, 0x14}, {0x61, 0x16} }, + /* temp1_min, humidity1_min */ + [limit_min] = { {0xe1, 0x02}, {0x61, 0x00} }, + /* temp_1_min_hyst, humidity1_min_hyst */ + [limit_min_hyst] = { {0xe1, 0x09}, {0x61, 0x0B} }, +}; + +#define SHT3X_NUM_LIMIT_CMD ARRAY_SIZE(limit_commands) + +static const u16 mode_to_update_interval[] = { + 0, + 2000, + 1000, + 500, + 250, + 100, +}; + +struct sht3x_data { + struct i2c_client *client; + struct mutex i2c_lock; /* lock for sending i2c commands */ + struct mutex data_lock; /* lock for updating driver data */ + + u8 mode; + const unsigned char *command; + u32 wait_time; /* in us*/ + unsigned long last_update; /* last update in periodic mode*/ + + struct sht3x_platform_data setup; + + /* + * cached values for temperature and humidity and limits + * the limits arrays have the following order: + * max, max_hyst, min, min_hyst + */ + int temperature; + int temperature_limits[SHT3X_NUM_LIMIT_CMD]; + u32 humidity; + u32 humidity_limits[SHT3X_NUM_LIMIT_CMD]; +}; + +static u8 get_mode_from_update_interval(u16 value) +{ + size_t index; + u8 number_of_modes = ARRAY_SIZE(mode_to_update_interval); + + if (value == 0) + return 0; + + /* find next faster update interval */ + for (index = 1; index < number_of_modes; index++) { + if (mode_to_update_interval[index] <= value) + return index; + } + + return number_of_modes - 1; +} + +static int sht3x_read_from_command(struct i2c_client *client, + struct sht3x_data *data, + const char *command, + char *buf, int length, u32 wait_time) +{ + int ret; + + mutex_lock(&data->i2c_lock); + ret = i2c_master_send(client, command, SHT3X_CMD_LENGTH); + + if (ret != SHT3X_CMD_LENGTH) { + ret = ret < 0 ? ret : -EIO; + goto out; + } + + if (wait_time) + usleep_range(wait_time, wait_time + 1000); + + ret = i2c_master_recv(client, buf, length); + if (ret != length) { + ret = ret < 0 ? ret : -EIO; + goto out; + } + + ret = 0; +out: + mutex_unlock(&data->i2c_lock); + return ret; +} + +static int sht3x_extract_temperature(u16 raw) +{ + /* + * From datasheet: + * T = -45 + 175 * ST / 2^16 + * Adapted for integer fixed point (3 digit) arithmetic. + */ + return ((21875 * (int)raw) >> 13) - 45000; +} + +static u32 sht3x_extract_humidity(u16 raw) +{ + /* + * From datasheet: + * RH = 100 * SRH / 2^16 + * Adapted for integer fixed point (3 digit) arithmetic. + */ + return (12500 * (u32)raw) >> 13; +} + +static struct sht3x_data *sht3x_update_client(struct device *dev) +{ + struct sht3x_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + u16 interval_ms = mode_to_update_interval[data->mode]; + unsigned long interval_jiffies = msecs_to_jiffies(interval_ms); + unsigned char buf[SHT3X_RESPONSE_LENGTH]; + u16 val; + int ret = 0; + + mutex_lock(&data->data_lock); + /* + * Only update cached readings once per update interval in periodic + * mode. In single shot mode the sensor measures values on demand, so + * every time the sysfs interface is called, a measurement is triggered. + * In periodic mode however, the measurement process is handled + * internally by the sensor and reading out sensor values only makes + * sense if a new reading is available. + */ + if (time_after(jiffies, data->last_update + interval_jiffies)) { + ret = sht3x_read_from_command(client, data, data->command, buf, + sizeof(buf), data->wait_time); + if (ret) + goto out; + + val = be16_to_cpup((__be16 *)buf); + data->temperature = sht3x_extract_temperature(val); + val = be16_to_cpup((__be16 *)(buf + 3)); + data->humidity = sht3x_extract_humidity(val); + data->last_update = jiffies; + } + +out: + mutex_unlock(&data->data_lock); + if (ret) + return ERR_PTR(ret); + + return data; +} + +/* sysfs attributes */ +static ssize_t temp1_input_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", data->temperature); +} + +static ssize_t humidity1_input_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sht3x_data *data = sht3x_update_client(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%u\n", data->humidity); +} + +/* + * limits_update must only be called from probe or with data_lock held + */ +static int limits_update(struct sht3x_data *data) +{ + int ret; + u8 index; + int temperature; + u32 humidity; + u16 raw; + char buffer[SHT3X_RESPONSE_LENGTH]; + const struct sht3x_limit_commands *commands; + struct i2c_client *client = data->client; + + for (index = 0; index < SHT3X_NUM_LIMIT_CMD; index++) { + commands = &limit_commands[index]; + ret = sht3x_read_from_command(client, data, + commands->read_command, buffer, + SHT3X_RESPONSE_LENGTH, 0); + + if (ret) + return ret; + + raw = be16_to_cpup((__be16 *)buffer); + temperature = sht3x_extract_temperature((raw & 0x01ff) << 7); + humidity = sht3x_extract_humidity(raw & 0xfe00); + data->temperature_limits[index] = temperature; + data->humidity_limits[index] = humidity; + } + + return ret; +} + +static ssize_t temp1_limit_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sht3x_data *data = dev_get_drvdata(dev); + u8 index = to_sensor_dev_attr(attr)->index; + int temperature_limit = data->temperature_limits[index]; + + return scnprintf(buf, PAGE_SIZE, "%d\n", temperature_limit); +} + +static ssize_t humidity1_limit_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sht3x_data *data = dev_get_drvdata(dev); + u8 index = to_sensor_dev_attr(attr)->index; + u32 humidity_limit = data->humidity_limits[index]; + + return scnprintf(buf, PAGE_SIZE, "%u\n", humidity_limit); +} + +/* + * limit_store must only be called with data_lock held + */ +static size_t limit_store(struct device *dev, + size_t count, + u8 index, + int temperature, + u32 humidity) +{ + char buffer[SHT3X_CMD_LENGTH + SHT3X_WORD_LEN + SHT3X_CRC8_LEN]; + char *position = buffer; + int ret; + u16 raw; + struct sht3x_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + const struct sht3x_limit_commands *commands; + + commands = &limit_commands[index]; + + memcpy(position, commands->write_command, SHT3X_CMD_LENGTH); + position += SHT3X_CMD_LENGTH; + /* + * ST = (T + 45) / 175 * 2^16 + * SRH = RH / 100 * 2^16 + * adapted for fixed point arithmetic and packed the same as + * in limit_show() + */ + raw = ((u32)(temperature + 45000) * 24543) >> (16 + 7); + raw |= ((humidity * 42950) >> 16) & 0xfe00; + + *((__be16 *)position) = cpu_to_be16(raw); + position += SHT3X_WORD_LEN; + *position = crc8(sht3x_crc8_table, + position - SHT3X_WORD_LEN, + SHT3X_WORD_LEN, + SHT3X_CRC8_INIT); + + mutex_lock(&data->i2c_lock); + ret = i2c_master_send(client, buffer, sizeof(buffer)); + mutex_unlock(&data->i2c_lock); + + if (ret != sizeof(buffer)) + return ret < 0 ? ret : -EIO; + + data->temperature_limits[index] = temperature; + data->humidity_limits[index] = humidity; + return count; +} + +static ssize_t temp1_limit_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int temperature; + int ret; + struct sht3x_data *data = dev_get_drvdata(dev); + u8 index = to_sensor_dev_attr(attr)->index; + + ret = kstrtoint(buf, 0, &temperature); + if (ret) + return ret; + + temperature = clamp_val(temperature, SHT3X_MIN_TEMPERATURE, + SHT3X_MAX_TEMPERATURE); + mutex_lock(&data->data_lock); + ret = limit_store(dev, count, index, temperature, + data->humidity_limits[index]); + mutex_unlock(&data->data_lock); + + return ret; +} + +static ssize_t humidity1_limit_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + u32 humidity; + int ret; + struct sht3x_data *data = dev_get_drvdata(dev); + u8 index = to_sensor_dev_attr(attr)->index; + + ret = kstrtou32(buf, 0, &humidity); + if (ret) + return ret; + + humidity = clamp_val(humidity, SHT3X_MIN_HUMIDITY, SHT3X_MAX_HUMIDITY); + mutex_lock(&data->data_lock); + ret = limit_store(dev, count, index, data->temperature_limits[index], + humidity); + mutex_unlock(&data->data_lock); + + return ret; +} + +static void sht3x_select_command(struct sht3x_data *data) +{ + /* + * In blocking mode (clock stretching mode) the I2C bus + * is blocked for other traffic, thus the call to i2c_master_recv() + * will wait until the data is ready. For non blocking mode, we + * have to wait ourselves. + */ + if (data->mode > 0) { + data->command = sht3x_cmd_measure_periodic_mode; + data->wait_time = 0; + } else if (data->setup.blocking_io) { + data->command = data->setup.high_precision ? + sht3x_cmd_measure_blocking_hpm : + sht3x_cmd_measure_blocking_lpm; + data->wait_time = 0; + } else { + if (data->setup.high_precision) { + data->command = sht3x_cmd_measure_nonblocking_hpm; + data->wait_time = SHT3X_NONBLOCKING_WAIT_TIME_HPM; + } else { + data->command = sht3x_cmd_measure_nonblocking_lpm; + data->wait_time = SHT3X_NONBLOCKING_WAIT_TIME_LPM; + } + } +} + +static int status_register_read(struct device *dev, + struct device_attribute *attr, + char *buffer, int length) +{ + int ret; + struct sht3x_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + + ret = sht3x_read_from_command(client, data, sht3x_cmd_read_status_reg, + buffer, length, 0); + + return ret; +} + +static ssize_t temp1_alarm_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN]; + int ret; + + ret = status_register_read(dev, attr, buffer, + SHT3X_WORD_LEN + SHT3X_CRC8_LEN); + if (ret) + return ret; + + return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x04)); +} + +static ssize_t humidity1_alarm_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN]; + int ret; + + ret = status_register_read(dev, attr, buffer, + SHT3X_WORD_LEN + SHT3X_CRC8_LEN); + if (ret) + return ret; + + return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x08)); +} + +static ssize_t update_interval_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sht3x_data *data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", + mode_to_update_interval[data->mode]); +} + +static ssize_t update_interval_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + u16 update_interval; + u8 mode; + int ret; + const char *command; + struct sht3x_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + + ret = kstrtou16(buf, 0, &update_interval); + if (ret) + return ret; + + mode = get_mode_from_update_interval(update_interval); + + mutex_lock(&data->data_lock); + /* mode did not change */ + if (mode == data->mode) { + mutex_unlock(&data->data_lock); + return count; + } + + mutex_lock(&data->i2c_lock); + /* + * Abort periodic measure mode. + * To do any changes to the configuration while in periodic mode, we + * have to send a break command to the sensor, which then falls back + * to single shot (mode = 0). + */ + if (data->mode > 0) { + ret = i2c_master_send(client, sht3x_cmd_break, + SHT3X_CMD_LENGTH); + if (ret != SHT3X_CMD_LENGTH) + goto out; + data->mode = 0; + } + + if (mode > 0) { + if (data->setup.high_precision) + command = periodic_measure_commands_hpm[mode - 1]; + else + command = periodic_measure_commands_lpm[mode - 1]; + + /* select mode */ + ret = i2c_master_send(client, command, SHT3X_CMD_LENGTH); + if (ret != SHT3X_CMD_LENGTH) + goto out; + } + + /* select mode and command */ + data->mode = mode; + sht3x_select_command(data); + +out: + mutex_unlock(&data->i2c_lock); + mutex_unlock(&data->data_lock); + if (ret != SHT3X_CMD_LENGTH) + return ret < 0 ? ret : -EIO; + + return count; +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, temp1_input_show, NULL, 0); +static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, humidity1_input_show, + NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, + temp1_limit_show, temp1_limit_store, + limit_max); +static SENSOR_DEVICE_ATTR(humidity1_max, S_IRUGO | S_IWUSR, + humidity1_limit_show, humidity1_limit_store, + limit_max); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, + temp1_limit_show, temp1_limit_store, + limit_max_hyst); +static SENSOR_DEVICE_ATTR(humidity1_max_hyst, S_IRUGO | S_IWUSR, + humidity1_limit_show, humidity1_limit_store, + limit_max_hyst); +static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, + temp1_limit_show, temp1_limit_store, + limit_min); +static SENSOR_DEVICE_ATTR(humidity1_min, S_IRUGO | S_IWUSR, + humidity1_limit_show, humidity1_limit_store, + limit_min); +static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO | S_IWUSR, + temp1_limit_show, temp1_limit_store, + limit_min_hyst); +static SENSOR_DEVICE_ATTR(humidity1_min_hyst, S_IRUGO | S_IWUSR, + humidity1_limit_show, humidity1_limit_store, + limit_min_hyst); +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, temp1_alarm_show, NULL, 0); +static SENSOR_DEVICE_ATTR(humidity1_alarm, S_IRUGO, humidity1_alarm_show, + NULL, 0); +static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, + update_interval_show, update_interval_store, 0); + +static struct attribute *sht3x_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_humidity1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_humidity1_max.dev_attr.attr, + &sensor_dev_attr_humidity1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, + &sensor_dev_attr_humidity1_min.dev_attr.attr, + &sensor_dev_attr_humidity1_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_humidity1_alarm.dev_attr.attr, + &sensor_dev_attr_update_interval.dev_attr.attr, + NULL +}; + +static struct attribute *sts3x_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + NULL +}; + +ATTRIBUTE_GROUPS(sht3x); +ATTRIBUTE_GROUPS(sts3x); + +static int sht3x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct sht3x_data *data; + struct device *hwmon_dev; + struct i2c_adapter *adap = client->adapter; + struct device *dev = &client->dev; + const struct attribute_group **attribute_groups; + + /* + * we require full i2c support since the sht3x uses multi-byte read and + * writes as well as multi-byte commands which are not supported by + * the smbus protocol + */ + if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) + return -ENODEV; + + ret = i2c_master_send(client, sht3x_cmd_clear_status_reg, + SHT3X_CMD_LENGTH); + if (ret != SHT3X_CMD_LENGTH) + return ret < 0 ? ret : -ENODEV; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->setup.blocking_io = false; + data->setup.high_precision = true; + data->mode = 0; + data->last_update = 0; + data->client = client; + crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL); + + if (client->dev.platform_data) + data->setup = *(struct sht3x_platform_data *)dev->platform_data; + + sht3x_select_command(data); + + mutex_init(&data->i2c_lock); + mutex_init(&data->data_lock); + + ret = limits_update(data); + if (ret) + return ret; + + if (id->driver_data == sts3x) + attribute_groups = sts3x_groups; + else + attribute_groups = sht3x_groups; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, + client->name, + data, + attribute_groups); + + if (IS_ERR(hwmon_dev)) + dev_dbg(dev, "unable to register hwmon device\n"); + + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +/* device ID table */ +static const struct i2c_device_id sht3x_ids[] = { + {"sht3x", sht3x}, + {"sts3x", sts3x}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, sht3x_ids); + +static struct i2c_driver sht3x_i2c_driver = { + .driver.name = "sht3x", + .probe = sht3x_probe, + .id_table = sht3x_ids, +}; + +module_i2c_driver(sht3x_i2c_driver); + +MODULE_AUTHOR("David Frey "); +MODULE_AUTHOR("Pascal Sachs "); +MODULE_DESCRIPTION("Sensirion SHT3x humidity and temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/platform_data/sht3x.h b/include/linux/platform_data/sht3x.h new file mode 100644 index 000000000000..2e5eea358194 --- /dev/null +++ b/include/linux/platform_data/sht3x.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 Sensirion AG, Switzerland + * Author: David Frey + * Author: Pascal Sachs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __SHT3X_H_ +#define __SHT3X_H_ + +struct sht3x_platform_data { + bool blocking_io; + bool high_precision; +}; +#endif /* __SHT3X_H_ */ -- cgit v1.3-14-g43fede From c0a68601804dcb4ee8a141e42e1e6893b6b0610c Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Wed, 8 Jun 2016 12:00:54 -0500 Subject: hwmon: (tmp401) Add support for TI TMP461 Signed-off-by: Andrew F. Davis Signed-off-by: Guenter Roeck --- Documentation/hwmon/tmp401 | 14 ++++++++++++-- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/tmp401.c | 35 +++++++++++++++++++++++++++++------ 3 files changed, 42 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/tmp401 b/Documentation/hwmon/tmp401 index 711f75e189eb..2d9ca42213cf 100644 --- a/Documentation/hwmon/tmp401 +++ b/Documentation/hwmon/tmp401 @@ -22,6 +22,9 @@ Supported chips: Prefix: 'tmp435' Addresses scanned: I2C 0x48 - 0x4f Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html + * Texas Instruments TMP461 + Prefix: 'tmp461' + Datasheet: http://www.ti.com/product/tmp461 Authors: Hans de Goede @@ -31,8 +34,8 @@ Description ----------- This driver implements support for Texas Instruments TMP401, TMP411, -TMP431, TMP432 and TMP435 chips. These chips implement one or two remote -and one local temperature sensors. Temperature is measured in degrees +TMP431, TMP432, TMP435, and TMP461 chips. These chips implement one or two +remote and one local temperature sensors. Temperature is measured in degrees Celsius. Resolution of the remote sensor is 0.0625 degree. Local sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not supported by the driver so far, so using the default resolution of 0.5 @@ -55,3 +58,10 @@ some additional features. TMP432 is compatible with TMP401 and TMP431. It supports two external temperature sensors. + +TMP461 is compatible with TMP401. It supports offset correction +that is applied to the remote sensor. + +* Sensor offset values are temperature values + + Exported via sysfs attribute tempX_offset diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index e0be99a4615c..be63b140a976 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1572,7 +1572,7 @@ config SENSORS_TMP401 depends on I2C help If you say yes here you get support for Texas Instruments TMP401, - TMP411, TMP431, TMP432 and TMP435 temperature sensor chips. + TMP411, TMP431, TMP432, TMP435, and TMP461 temperature sensor chips. This driver can also be built as a module. If so, the module will be called tmp401. diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ccf4cffe0ee1..eeeed2c7d081 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -47,7 +47,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; -enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; +enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; /* * The TMP401 registers, note some registers have different addresses for @@ -62,31 +62,34 @@ enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; #define TMP401_MANUFACTURER_ID_REG 0xFE #define TMP401_DEVICE_ID_REG 0xFF -static const u8 TMP401_TEMP_MSB_READ[6][2] = { +static const u8 TMP401_TEMP_MSB_READ[7][2] = { { 0x00, 0x01 }, /* temp */ { 0x06, 0x08 }, /* low limit */ { 0x05, 0x07 }, /* high limit */ { 0x20, 0x19 }, /* therm (crit) limit */ { 0x30, 0x34 }, /* lowest */ { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ }; -static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { +static const u8 TMP401_TEMP_MSB_WRITE[7][2] = { { 0, 0 }, /* temp (unused) */ { 0x0C, 0x0E }, /* low limit */ { 0x0B, 0x0D }, /* high limit */ { 0x20, 0x19 }, /* therm (crit) limit */ { 0x30, 0x34 }, /* lowest */ { 0x32, 0x36 }, /* highest */ + { 0, 0x11 }, /* offset */ }; -static const u8 TMP401_TEMP_LSB[6][2] = { +static const u8 TMP401_TEMP_LSB[7][2] = { { 0x15, 0x10 }, /* temp */ { 0x17, 0x14 }, /* low limit */ { 0x16, 0x13 }, /* high limit */ { 0, 0 }, /* therm (crit) limit (unused) */ { 0x31, 0x35 }, /* lowest */ { 0x33, 0x37 }, /* highest */ + { 0, 0x12 }, /* offset */ }; static const u8 TMP432_TEMP_MSB_READ[4][3] = { @@ -149,6 +152,7 @@ static const struct i2c_device_id tmp401_id[] = { { "tmp431", tmp431 }, { "tmp432", tmp432 }, { "tmp435", tmp435 }, + { "tmp461", tmp461 }, { } }; MODULE_DEVICE_TABLE(i2c, tmp401_id); @@ -170,7 +174,7 @@ struct tmp401_data { /* register values */ u8 status[4]; u8 config; - u16 temp[6][3]; + u16 temp[7][3]; u8 temp_crit_hyst; }; @@ -612,6 +616,22 @@ static const struct attribute_group tmp432_group = { .attrs = tmp432_attributes, }; +/* + * Additional features of the TMP461 chip. + * The TMP461 temperature offset for the remote channel. + */ +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp, + store_temp, 6, 1); + +static struct attribute *tmp461_attributes[] = { + &sensor_dev_attr_temp2_offset.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp461_group = { + .attrs = tmp461_attributes, +}; + /* * Begin non sysfs callback code (aka Real code) */ @@ -714,7 +734,7 @@ static int tmp401_probe(struct i2c_client *client, const struct i2c_device_id *id) { static const char * const names[] = { - "TMP401", "TMP411", "TMP431", "TMP432", "TMP435" + "TMP401", "TMP411", "TMP431", "TMP432", "TMP435", "TMP461" }; struct device *dev = &client->dev; struct device *hwmon_dev; @@ -745,6 +765,9 @@ static int tmp401_probe(struct i2c_client *client, if (data->kind == tmp432) data->groups[groups++] = &tmp432_group; + if (data->kind == tmp461) + data->groups[groups++] = &tmp461_group; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, data->groups); if (IS_ERR(hwmon_dev)) -- cgit v1.3-14-g43fede From 7cb6dcff1956ec9e338abfa2f298d2971cfbab79 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 10 Jun 2016 10:32:33 -0500 Subject: hwmon: Add support for INA3221 Triple Current/Voltage Monitors Add support for the the INA3221 26v capable, Triple channel, Bi-Directional, Zero-Drift, Low-/High-Side, Current/Voltage Monitor with I2C interface. Signed-off-by: Andrew F. Davis Signed-off-by: Guenter Roeck --- Documentation/hwmon/ina3221 | 35 ++++ drivers/hwmon/Kconfig | 11 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/ina3221.c | 446 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 493 insertions(+) create mode 100644 Documentation/hwmon/ina3221 create mode 100644 drivers/hwmon/ina3221.c (limited to 'Documentation') diff --git a/Documentation/hwmon/ina3221 b/Documentation/hwmon/ina3221 new file mode 100644 index 000000000000..0ff74854cb2e --- /dev/null +++ b/Documentation/hwmon/ina3221 @@ -0,0 +1,35 @@ +Kernel driver ina3221 +===================== + +Supported chips: + * Texas Instruments INA3221 + Prefix: 'ina3221' + Addresses: I2C 0x40 - 0x43 + Datasheet: Publicly available at the Texas Instruments website + http://www.ti.com/ + +Author: Andrew F. Davis + +Description +----------- + +The Texas Instruments INA3221 monitors voltage, current, and power on the high +side of up to three D.C. power supplies. The INA3221 monitors both shunt drop +and supply voltage, with programmable conversion times and averaging, current +and power are calculated host-side from these. + +Sysfs entries +------------- + +in[123]_input Bus voltage(mV) channels +curr[123]_input Current(mA) measurement channels +shunt[123]_resistor Shunt resistance(uOhm) channels +curr[123]_crit Critical alert current(mA) setting, activates the + corresponding alarm when the respective current + is above this value +curr[123]_crit_alarm Critical alert current limit exceeded +curr[123]_max Warning alert current(mA) setting, activates the + corresponding alarm when the respective current + average is above this value. +curr[123]_max_alarm Warning alert current limit exceeded +in[456]_input Shunt voltage(uV) for channels 1, 2, and 3 respectively diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index be63b140a976..b2aa13bd89dc 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1525,6 +1525,17 @@ config SENSORS_INA2XX This driver can also be built as a module. If so, the module will be called ina2xx. +config SENSORS_INA3221 + tristate "Texas Instruments INA3221 Triple Power Monitor" + depends on I2C + select REGMAP_I2C + help + If you say yes here you get support for the TI INA3221 Triple Power + Monitor. + + This driver can also be built as a module. If so, the module + will be called ina3221. + config SENSORS_TC74 tristate "Microchip TC74" depends on I2C diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 406b18b995b3..446a4e74c7cf 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o obj-$(CONFIG_SENSORS_INA209) += ina209.o obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o +obj-$(CONFIG_SENSORS_INA3221) += ina3221.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_JC42) += jc42.o obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c new file mode 100644 index 000000000000..d055b6a2266b --- /dev/null +++ b/drivers/hwmon/ina3221.c @@ -0,0 +1,446 @@ +/* + * INA3221 Triple Current/Voltage Monitor + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#define INA3221_DRIVER_NAME "ina3221" + +#define INA3221_CONFIG 0x00 +#define INA3221_SHUNT1 0x01 +#define INA3221_BUS1 0x02 +#define INA3221_SHUNT2 0x03 +#define INA3221_BUS2 0x04 +#define INA3221_SHUNT3 0x05 +#define INA3221_BUS3 0x06 +#define INA3221_CRIT1 0x07 +#define INA3221_WARN1 0x08 +#define INA3221_CRIT2 0x09 +#define INA3221_WARN2 0x0a +#define INA3221_CRIT3 0x0b +#define INA3221_WARN3 0x0c +#define INA3221_MASK_ENABLE 0x0f + +#define INA3221_CONFIG_MODE_SHUNT BIT(1) +#define INA3221_CONFIG_MODE_BUS BIT(2) +#define INA3221_CONFIG_MODE_CONTINUOUS BIT(3) + +#define INA3221_RSHUNT_DEFAULT 10000 + +enum ina3221_fields { + /* Configuration */ + F_RST, + + /* Alert Flags */ + F_WF3, F_WF2, F_WF1, + F_CF3, F_CF2, F_CF1, + + /* sentinel */ + F_MAX_FIELDS +}; + +static const struct reg_field ina3221_reg_fields[] = { + [F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15), + + [F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3), + [F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4), + [F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5), + [F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7), + [F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8), + [F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9), +}; + +enum ina3221_channels { + INA3221_CHANNEL1, + INA3221_CHANNEL2, + INA3221_CHANNEL3, + INA3221_NUM_CHANNELS +}; + +static const unsigned int register_channel[] = { + [INA3221_SHUNT1] = INA3221_CHANNEL1, + [INA3221_SHUNT2] = INA3221_CHANNEL2, + [INA3221_SHUNT3] = INA3221_CHANNEL3, + [INA3221_CRIT1] = INA3221_CHANNEL1, + [INA3221_CRIT2] = INA3221_CHANNEL2, + [INA3221_CRIT3] = INA3221_CHANNEL3, + [INA3221_WARN1] = INA3221_CHANNEL1, + [INA3221_WARN2] = INA3221_CHANNEL2, + [INA3221_WARN3] = INA3221_CHANNEL3, +}; + +/** + * struct ina3221_data - device specific information + * @regmap: Register map of the device + * @fields: Register fields of the device + * @shunt_resistors: Array of resistor values per channel + */ +struct ina3221_data { + struct regmap *regmap; + struct regmap_field *fields[F_MAX_FIELDS]; + unsigned int shunt_resistors[INA3221_NUM_CHANNELS]; +}; + +static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, + int *val) +{ + unsigned int regval; + int ret; + + ret = regmap_read(ina->regmap, reg, ®val); + if (ret) + return ret; + + *val = sign_extend32(regval >> 3, 12); + + return 0; +} + +static ssize_t ina3221_show_bus_voltage(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int reg = sd_attr->index; + int val, voltage_mv, ret; + + ret = ina3221_read_value(ina, reg, &val); + if (ret) + return ret; + + voltage_mv = val * 8; + + return snprintf(buf, PAGE_SIZE, "%d\n", voltage_mv); +} + +static ssize_t ina3221_show_shunt_voltage(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int reg = sd_attr->index; + int val, voltage_uv, ret; + + ret = ina3221_read_value(ina, reg, &val); + if (ret) + return ret; + voltage_uv = val * 40; + + return snprintf(buf, PAGE_SIZE, "%d\n", voltage_uv); +} + +static ssize_t ina3221_show_current(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int reg = sd_attr->index; + unsigned int channel = register_channel[reg]; + unsigned int resistance_uo = ina->shunt_resistors[channel]; + int val, current_ma, voltage_nv, ret; + + ret = ina3221_read_value(ina, reg, &val); + if (ret) + return ret; + voltage_nv = val * 40000; + + current_ma = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo); + + return snprintf(buf, PAGE_SIZE, "%d\n", current_ma); +} + +static ssize_t ina3221_set_current(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int reg = sd_attr->index; + unsigned int channel = register_channel[reg]; + unsigned int resistance_uo = ina->shunt_resistors[channel]; + int val, current_ma, voltage_uv, ret; + + ret = kstrtoint(buf, 0, ¤t_ma); + if (ret) + return ret; + + /* clamp current */ + current_ma = clamp_val(current_ma, + INT_MIN / resistance_uo, + INT_MAX / resistance_uo); + + voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000); + + /* clamp voltage */ + voltage_uv = clamp_val(voltage_uv, -163800, 163800); + + /* 1 / 40uV(scale) << 3(register shift) = 5 */ + val = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8; + + ret = regmap_write(ina->regmap, reg, val); + if (ret) + return ret; + + return count; +} + +static ssize_t ina3221_show_shunt(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int channel = sd_attr->index; + unsigned int resistance_uo; + + resistance_uo = ina->shunt_resistors[channel]; + + return snprintf(buf, PAGE_SIZE, "%d\n", resistance_uo); +} + +static ssize_t ina3221_set_shunt(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int channel = sd_attr->index; + unsigned int val; + int ret; + + ret = kstrtouint(buf, 0, &val); + if (ret) + return ret; + + if (val == 0) + return -EINVAL; + + ina->shunt_resistors[channel] = val; + + return count; +} + +static ssize_t ina3221_show_alert(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr); + struct ina3221_data *ina = dev_get_drvdata(dev); + unsigned int field = sd_attr->index; + unsigned int regval; + int ret; + + ret = regmap_field_read(ina->fields[field], ®val); + if (ret) + return ret; + + return snprintf(buf, PAGE_SIZE, "%d\n", regval); +} + +/* bus voltage */ +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, + ina3221_show_bus_voltage, NULL, INA3221_BUS1); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, + ina3221_show_bus_voltage, NULL, INA3221_BUS2); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, + ina3221_show_bus_voltage, NULL, INA3221_BUS3); + +/* calculated current */ +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, + ina3221_show_current, NULL, INA3221_SHUNT1); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, + ina3221_show_current, NULL, INA3221_SHUNT2); +static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, + ina3221_show_current, NULL, INA3221_SHUNT3); + +/* shunt resistance */ +static SENSOR_DEVICE_ATTR(shunt1_resistor, S_IRUGO | S_IWUSR, + ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL1); +static SENSOR_DEVICE_ATTR(shunt2_resistor, S_IRUGO | S_IWUSR, + ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL2); +static SENSOR_DEVICE_ATTR(shunt3_resistor, S_IRUGO | S_IWUSR, + ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL3); + +/* critical current */ +static SENSOR_DEVICE_ATTR(curr1_crit, S_IRUGO | S_IWUSR, + ina3221_show_current, ina3221_set_current, INA3221_CRIT1); +static SENSOR_DEVICE_ATTR(curr2_crit, S_IRUGO | S_IWUSR, + ina3221_show_current, ina3221_set_current, INA3221_CRIT2); +static SENSOR_DEVICE_ATTR(curr3_crit, S_IRUGO | S_IWUSR, + ina3221_show_current, ina3221_set_current, INA3221_CRIT3); + +/* critical current alert */ +static SENSOR_DEVICE_ATTR(curr1_crit_alarm, S_IRUGO, + ina3221_show_alert, NULL, F_CF1); +static SENSOR_DEVICE_ATTR(curr2_crit_alarm, S_IRUGO, + ina3221_show_alert, NULL, F_CF2); +static SENSOR_DEVICE_ATTR(curr3_crit_alarm, S_IRUGO, + ina3221_show_alert, NULL, F_CF3); + +/* warning current */ +static SENSOR_DEVICE_ATTR(curr1_max, S_IRUGO | S_IWUSR, + ina3221_show_current, ina3221_set_current, INA3221_WARN1); +static SENSOR_DEVICE_ATTR(curr2_max, S_IRUGO | S_IWUSR, + ina3221_show_current, ina3221_set_current, INA3221_WARN2); +static SENSOR_DEVICE_ATTR(curr3_max, S_IRUGO | S_IWUSR, + ina3221_show_current, ina3221_set_current, INA3221_WARN3); + +/* warning current alert */ +static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, + ina3221_show_alert, NULL, F_WF1); +static SENSOR_DEVICE_ATTR(curr2_max_alarm, S_IRUGO, + ina3221_show_alert, NULL, F_WF2); +static SENSOR_DEVICE_ATTR(curr3_max_alarm, S_IRUGO, + ina3221_show_alert, NULL, F_WF3); + +/* shunt voltage */ +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, + ina3221_show_shunt_voltage, NULL, INA3221_SHUNT1); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, + ina3221_show_shunt_voltage, NULL, INA3221_SHUNT2); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, + ina3221_show_shunt_voltage, NULL, INA3221_SHUNT3); + +static struct attribute *ina3221_attrs[] = { + /* channel 1 */ + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_shunt1_resistor.dev_attr.attr, + &sensor_dev_attr_curr1_crit.dev_attr.attr, + &sensor_dev_attr_curr1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_curr1_max.dev_attr.attr, + &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + + /* channel 2 */ + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_shunt2_resistor.dev_attr.attr, + &sensor_dev_attr_curr2_crit.dev_attr.attr, + &sensor_dev_attr_curr2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_curr2_max.dev_attr.attr, + &sensor_dev_attr_curr2_max_alarm.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + + /* channel 3 */ + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_curr3_input.dev_attr.attr, + &sensor_dev_attr_shunt3_resistor.dev_attr.attr, + &sensor_dev_attr_curr3_crit.dev_attr.attr, + &sensor_dev_attr_curr3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_curr3_max.dev_attr.attr, + &sensor_dev_attr_curr3_max_alarm.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + + NULL, +}; +ATTRIBUTE_GROUPS(ina3221); + +static const struct regmap_range ina3221_yes_ranges[] = { + regmap_reg_range(INA3221_SHUNT1, INA3221_BUS3), + regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE), +}; + +static const struct regmap_access_table ina3221_volatile_table = { + .yes_ranges = ina3221_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges), +}; + +static const struct regmap_config ina3221_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + + .cache_type = REGCACHE_RBTREE, + .volatile_table = &ina3221_volatile_table, +}; + +static int ina3221_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct ina3221_data *ina; + struct device *hwmon_dev; + int i, ret; + + ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL); + if (!ina) + return -ENOMEM; + + ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config); + if (IS_ERR(ina->regmap)) { + dev_err(dev, "Unable to allocate register map\n"); + return PTR_ERR(ina->regmap); + } + + for (i = 0; i < F_MAX_FIELDS; i++) { + ina->fields[i] = devm_regmap_field_alloc(dev, + ina->regmap, + ina3221_reg_fields[i]); + if (IS_ERR(ina->fields[i])) { + dev_err(dev, "Unable to allocate regmap fields\n"); + return PTR_ERR(ina->fields[i]); + } + } + + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + ina->shunt_resistors[i] = INA3221_RSHUNT_DEFAULT; + + ret = regmap_field_write(ina->fields[F_RST], true); + if (ret) { + dev_err(dev, "Unable to reset device\n"); + return ret; + } + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, + client->name, + ina, ina3221_groups); + if (IS_ERR(hwmon_dev)) { + dev_err(dev, "Unable to register hwmon device\n"); + return PTR_ERR(hwmon_dev); + } + + return 0; +} + +static const struct of_device_id ina3221_of_match_table[] = { + { .compatible = "ti,ina3221", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ina3221_of_match_table); + +static const struct i2c_device_id ina3221_ids[] = { + { "ina3221", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(i2c, ina3221_ids); + +static struct i2c_driver ina3221_i2c_driver = { + .probe = ina3221_probe, + .driver = { + .name = INA3221_DRIVER_NAME, + .of_match_table = ina3221_of_match_table, + }, + .id_table = ina3221_ids, +}; +module_i2c_driver(ina3221_i2c_driver); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.3-14-g43fede From 165720d9ff3e33f626802da6cef3118ebfc6940c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 10 Jun 2016 21:01:28 -0700 Subject: hwmon: Update guildelines for submitting patches Add more details to the guidelines for submitting patches. Signed-off-by: Guenter Roeck --- Documentation/hwmon/submitting-patches | 40 +++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/submitting-patches b/Documentation/hwmon/submitting-patches index d201828d202f..57f60307accc 100644 --- a/Documentation/hwmon/submitting-patches +++ b/Documentation/hwmon/submitting-patches @@ -15,10 +15,15 @@ increase the chances of your change being accepted. Documentation/SubmittingPatches Documentation/CodingStyle -* If your patch generates checkpatch warnings, please refrain from explanations - such as "I don't like that coding style". Keep in mind that each unnecessary - warning helps hiding a real problem. If you don't like the kernel coding - style, don't write kernel drivers. +* Please run your patch through 'checkpatch --strict'. There should be no + errors, no warnings, and few if any check messages. If there are any + messages, please be prepared to explain. + +* If your patch generates checkpatch errors, warnings, or check messages, + please refrain from explanations such as "I prefer that coding style". + Keep in mind that each unnecessary message helps hiding a real problem, + and a consistent coding style makes it easier for others to understand + and review the code. * Please test your patch thoroughly. We are not your test group. Sometimes a patch can not or not completely be tested because of missing @@ -61,15 +66,30 @@ increase the chances of your change being accepted. * Make sure that all dependencies are listed in Kconfig. +* Please list include files in alphabetic order. + +* Please align continuation lines with '(' on the previous line. + * Avoid forward declarations if you can. Rearrange the code if necessary. +* Avoid macros to generate groups of sensor attributes. It not only confuses + checkpatch, but also makes it more difficult to review the code. + * Avoid calculations in macros and macro-generated functions. While such macros may save a line or so in the source, it obfuscates the code and makes code review more difficult. It may also result in code which is more complicated than necessary. Use inline functions or just regular functions instead. +* Limit the number of kernel log messages. In general, your driver should not + generate an error message just because a runtime operation failed. Report + errors to user space instead, using an appropriate error code. Keep in mind + that kernel error log messages not only fill up the kernel log, but also are + printed synchronously, most likely with interrupt disabled, often to a serial + console. Excessive logging can seriously affect system performance. + * Use devres functions whenever possible to allocate resources. For rationale and supported functions, please see Documentation/driver-model/devres.txt. + If a function is not supported by devres, consider using devm_add_action(). * If the driver has a detect function, make sure it is silent. Debug messages and messages printed after a successful detection are acceptable, but it @@ -96,8 +116,16 @@ increase the chances of your change being accepted. writing to it might cause a bad misconfiguration. * Make sure there are no race conditions in the probe function. Specifically, - completely initialize your chip first, then create sysfs entries and register - with the hwmon subsystem. + completely initialize your chip and your driver first, then register with + the hwmon subsystem. + +* Use devm_hwmon_device_register_with_groups() or, if your driver needs a remove + function, hwmon_device_register_with_groups() to register your driver with the + hwmon subsystem. Try using devm_add_action() instead of a remove function if + possible. Do not use hwmon_device_register(). + +* Your driver should be buildable as module. If not, please be prepared to + explain why it has to be built into the kernel. * Do not provide support for deprecated sysfs attributes. -- cgit v1.3-14-g43fede From a31887dc9be1a65cde2562ed10e7fbf5c82581a2 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Mon, 27 Jun 2016 17:23:27 -0700 Subject: hwmon: (jc42) Add support for Microchip MCP9808 temperature sensor MCP9808 is not officially compliant to JC-42, similar to MCP9804, but its registers are compatible to JC-42. Signed-off-by: Alison Schofield Cc: Daniel Baluta Signed-off-by: Guenter Roeck --- Documentation/hwmon/jc42 | 3 ++- drivers/hwmon/Kconfig | 4 ++-- drivers/hwmon/jc42.c | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/jc42 b/Documentation/hwmon/jc42 index f7f1830a2566..b4b671f22453 100644 --- a/Documentation/hwmon/jc42 +++ b/Documentation/hwmon/jc42 @@ -18,10 +18,11 @@ Supported chips: * Maxim MAX6604 Datasheets: http://datasheets.maxim-ic.com/en/ds/MAX6604.pdf - * Microchip MCP9804, MCP9805, MCP98242, MCP98243, MCP98244, MCP9843 + * Microchip MCP9804, MCP9805, MCP9808, MCP98242, MCP98243, MCP98244, MCP9843 Datasheets: http://ww1.microchip.com/downloads/en/DeviceDoc/22203C.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/21977b.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/25095A.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/21996a.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/22153c.pdf http://ww1.microchip.com/downloads/en/DeviceDoc/22327A.pdf diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index b2aa13bd89dc..91f145e0cd45 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -645,8 +645,8 @@ config SENSORS_JC42 temperature sensors, which are used on many DDR3 memory modules for mobile devices and servers. Support will include, but not be limited to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805, - MCP98242, MCP98243, MCP98244, MCP9843, SE97, SE98, STTS424(E), - STTS2002, STTS3000, TSE2002, TSE2004, TS3000, and TS3001. + MCP9808, MCP98242, MCP98243, MCP98244, MCP9843, SE97, SE98, + STTS424(E), STTS2002, STTS3000, TSE2002, TSE2004, TS3000, and TS3001. This driver can also be built as a module. If so, the module will be called jc42. diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 9887d3224a86..f67c1bbe2c51 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -104,6 +104,9 @@ static const unsigned short normal_i2c[] = { #define MCP9804_DEVID 0x0200 #define MCP9804_DEVID_MASK 0xfffc +#define MCP9808_DEVID 0x0400 +#define MCP9808_DEVID_MASK 0xfffc + #define MCP98242_DEVID 0x2000 #define MCP98242_DEVID_MASK 0xfffc @@ -160,6 +163,7 @@ static struct jc42_chips jc42_chips[] = { { IDT_MANID, TS3001_DEVID, TS3001_DEVID_MASK }, { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK }, + { MCP_MANID, MCP9808_DEVID, MCP9808_DEVID_MASK }, { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK }, { MCP_MANID, MCP98244_DEVID, MCP98244_DEVID_MASK }, -- cgit v1.3-14-g43fede From 93dd49d0028c66be9f0404d23dd6817b876cc6dc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 10 Jun 2016 10:40:06 +0200 Subject: s390/oprofile: remove hardware sampler support Remove hardware sampler support from oprofile module. The oprofile user space utilty has been switched to use the kernel perf interface, for which we also provide hardware sampling support. In addition the hardware sampling support is also slightly broken: it supports only 16 bits for the pid and therefore would generate wrong results on machines which have a pid >64k. Also the pt_regs structure which was passed to oprofile common code cannot necessarily be used to generate sane backtraces, since the task(s) in question may run while the samples are fed to oprofile. So the result would be more or less random. However given that the only user space tools switched to the perf interface already four years ago the hardware sampler code seems to be unused code, and therefore it should be reasonable to remove it. The timer based oprofile support continues to work. Signed-off-by: Heiko Carstens Acked-by: Andreas Arnez Acked-by: Andreas Krebbel Acked-by: Robert Richter Reviewed-by: Hendrik Brueckner Signed-off-by: Martin Schwidefsky --- Documentation/kernel-parameters.txt | 2 - arch/s390/oprofile/Makefile | 1 - arch/s390/oprofile/hwsampler.c | 1178 ----------------------------------- arch/s390/oprofile/hwsampler.h | 63 -- arch/s390/oprofile/init.c | 489 --------------- arch/s390/oprofile/op_counter.h | 21 - 6 files changed, 1754 deletions(-) delete mode 100644 arch/s390/oprofile/hwsampler.c delete mode 100644 arch/s390/oprofile/hwsampler.h delete mode 100644 arch/s390/oprofile/op_counter.h (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..68b0c022861a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2788,8 +2788,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. timer: [X86] Force use of architectural NMI timer mode (see also oprofile.timer for generic hr timer mode) - [s390] Force legacy basic mode sampling - (report cpu_type "timer") oops=panic Always panic on oopses. Default is to just kill the process, but there is a small probability of diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile index 496e4a7ee00e..e9dd41b0b8d3 100644 --- a/arch/s390/oprofile/Makefile +++ b/arch/s390/oprofile/Makefile @@ -7,4 +7,3 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) oprofile-y := $(DRIVER_OBJS) init.o -oprofile-y += hwsampler.o diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c deleted file mode 100644 index ff9b4eb34589..000000000000 --- a/arch/s390/oprofile/hwsampler.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * Copyright IBM Corp. 2010 - * Author: Heinz Graalfs - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "hwsampler.h" -#include "op_counter.h" - -#define MAX_NUM_SDB 511 -#define MIN_NUM_SDB 1 - -DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); - -struct hws_execute_parms { - void *buffer; - signed int rc; -}; - -DEFINE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); -EXPORT_PER_CPU_SYMBOL(sampler_cpu_buffer); - -static DEFINE_MUTEX(hws_sem); -static DEFINE_MUTEX(hws_sem_oom); - -static unsigned char hws_flush_all; -static unsigned int hws_oom; -static unsigned int hws_alert; -static struct workqueue_struct *hws_wq; - -static unsigned int hws_state; -enum { - HWS_INIT = 1, - HWS_DEALLOCATED, - HWS_STOPPED, - HWS_STARTED, - HWS_STOPPING }; - -/* set to 1 if called by kernel during memory allocation */ -static unsigned char oom_killer_was_active; -/* size of SDBT and SDB as of allocate API */ -static unsigned long num_sdbt = 100; -static unsigned long num_sdb = 511; -/* sampling interval (machine cycles) */ -static unsigned long interval; - -static unsigned long min_sampler_rate; -static unsigned long max_sampler_rate; - -static void execute_qsi(void *parms) -{ - struct hws_execute_parms *ep = parms; - - ep->rc = qsi(ep->buffer); -} - -static void execute_ssctl(void *parms) -{ - struct hws_execute_parms *ep = parms; - - ep->rc = lsctl(ep->buffer); -} - -static int smp_ctl_ssctl_stop(int cpu) -{ - int rc; - struct hws_execute_parms ep; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - cb->ssctl.es = 0; - cb->ssctl.cs = 0; - - ep.buffer = &cb->ssctl; - smp_call_function_single(cpu, execute_ssctl, &ep, 1); - rc = ep.rc; - if (rc) { - printk(KERN_ERR "hwsampler: CPU %d CPUMF SSCTL failed.\n", cpu); - dump_stack(); - } - - ep.buffer = &cb->qsi; - smp_call_function_single(cpu, execute_qsi, &ep, 1); - - if (cb->qsi.es || cb->qsi.cs) { - printk(KERN_EMERG "CPUMF sampling did not stop properly.\n"); - dump_stack(); - } - - return rc; -} - -static int smp_ctl_ssctl_deactivate(int cpu) -{ - int rc; - struct hws_execute_parms ep; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - cb->ssctl.es = 1; - cb->ssctl.cs = 0; - - ep.buffer = &cb->ssctl; - smp_call_function_single(cpu, execute_ssctl, &ep, 1); - rc = ep.rc; - if (rc) - printk(KERN_ERR "hwsampler: CPU %d CPUMF SSCTL failed.\n", cpu); - - ep.buffer = &cb->qsi; - smp_call_function_single(cpu, execute_qsi, &ep, 1); - - if (cb->qsi.cs) - printk(KERN_EMERG "CPUMF sampling was not set inactive.\n"); - - return rc; -} - -static int smp_ctl_ssctl_enable_activate(int cpu, unsigned long interval) -{ - int rc; - struct hws_execute_parms ep; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - cb->ssctl.h = 1; - cb->ssctl.tear = cb->first_sdbt; - cb->ssctl.dear = *(unsigned long *) cb->first_sdbt; - cb->ssctl.interval = interval; - cb->ssctl.es = 1; - cb->ssctl.cs = 1; - - ep.buffer = &cb->ssctl; - smp_call_function_single(cpu, execute_ssctl, &ep, 1); - rc = ep.rc; - if (rc) - printk(KERN_ERR "hwsampler: CPU %d CPUMF SSCTL failed.\n", cpu); - - ep.buffer = &cb->qsi; - smp_call_function_single(cpu, execute_qsi, &ep, 1); - if (ep.rc) - printk(KERN_ERR "hwsampler: CPU %d CPUMF QSI failed.\n", cpu); - - return rc; -} - -static int smp_ctl_qsi(int cpu) -{ - struct hws_execute_parms ep; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - ep.buffer = &cb->qsi; - smp_call_function_single(cpu, execute_qsi, &ep, 1); - - return ep.rc; -} - -static void hws_ext_handler(struct ext_code ext_code, - unsigned int param32, unsigned long param64) -{ - struct hws_cpu_buffer *cb = this_cpu_ptr(&sampler_cpu_buffer); - - if (!(param32 & CPU_MF_INT_SF_MASK)) - return; - - if (!hws_alert) - return; - - inc_irq_stat(IRQEXT_CMS); - atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); - - if (hws_wq) - queue_work(hws_wq, &cb->worker); -} - -static void worker(struct work_struct *work); - -static void add_samples_to_oprofile(unsigned cpu, unsigned long *, - unsigned long *dear); - -static void init_all_cpu_buffers(void) -{ - int cpu; - struct hws_cpu_buffer *cb; - - for_each_online_cpu(cpu) { - cb = &per_cpu(sampler_cpu_buffer, cpu); - memset(cb, 0, sizeof(struct hws_cpu_buffer)); - } -} - -static void prepare_cpu_buffers(void) -{ - struct hws_cpu_buffer *cb; - int cpu; - - for_each_online_cpu(cpu) { - cb = &per_cpu(sampler_cpu_buffer, cpu); - atomic_set(&cb->ext_params, 0); - cb->worker_entry = 0; - cb->sample_overflow = 0; - cb->req_alert = 0; - cb->incorrect_sdbt_entry = 0; - cb->invalid_entry_address = 0; - cb->loss_of_sample_data = 0; - cb->sample_auth_change_alert = 0; - cb->finish = 0; - cb->oom = 0; - cb->stop_mode = 0; - } -} - -/* - * allocate_sdbt() - allocate sampler memory - * @cpu: the cpu for which sampler memory is allocated - * - * A 4K page is allocated for each requested SDBT. - * A maximum of 511 4K pages are allocated for the SDBs in each of the SDBTs. - * Set ALERT_REQ mask in each SDBs trailer. - * Returns zero if successful, <0 otherwise. - */ -static int allocate_sdbt(int cpu) -{ - int j, k, rc; - unsigned long *sdbt; - unsigned long sdb; - unsigned long *tail; - unsigned long *trailer; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - if (cb->first_sdbt) - return -EINVAL; - - sdbt = NULL; - tail = sdbt; - - for (j = 0; j < num_sdbt; j++) { - sdbt = (unsigned long *)get_zeroed_page(GFP_KERNEL); - - mutex_lock(&hws_sem_oom); - /* OOM killer might have been activated */ - barrier(); - if (oom_killer_was_active || !sdbt) { - if (sdbt) - free_page((unsigned long)sdbt); - - goto allocate_sdbt_error; - } - if (cb->first_sdbt == 0) - cb->first_sdbt = (unsigned long)sdbt; - - /* link current page to tail of chain */ - if (tail) - *tail = (unsigned long)(void *)sdbt + 1; - - mutex_unlock(&hws_sem_oom); - - for (k = 0; k < num_sdb; k++) { - /* get and set SDB page */ - sdb = get_zeroed_page(GFP_KERNEL); - - mutex_lock(&hws_sem_oom); - /* OOM killer might have been activated */ - barrier(); - if (oom_killer_was_active || !sdb) { - if (sdb) - free_page(sdb); - - goto allocate_sdbt_error; - } - *sdbt = sdb; - trailer = trailer_entry_ptr(*sdbt); - *trailer = SDB_TE_ALERT_REQ_MASK; - sdbt++; - mutex_unlock(&hws_sem_oom); - } - tail = sdbt; - } - mutex_lock(&hws_sem_oom); - if (oom_killer_was_active) - goto allocate_sdbt_error; - - rc = 0; - if (tail) - *tail = (unsigned long) - ((void *)cb->first_sdbt) + 1; - -allocate_sdbt_exit: - mutex_unlock(&hws_sem_oom); - return rc; - -allocate_sdbt_error: - rc = -ENOMEM; - goto allocate_sdbt_exit; -} - -/* - * deallocate_sdbt() - deallocate all sampler memory - * - * For each online CPU all SDBT trees are deallocated. - * Returns the number of freed pages. - */ -static int deallocate_sdbt(void) -{ - int cpu; - int counter; - - counter = 0; - - for_each_online_cpu(cpu) { - unsigned long start; - unsigned long sdbt; - unsigned long *curr; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - if (!cb->first_sdbt) - continue; - - sdbt = cb->first_sdbt; - curr = (unsigned long *) sdbt; - start = sdbt; - - /* we'll free the SDBT after all SDBs are processed... */ - while (1) { - if (!*curr || !sdbt) - break; - - /* watch for link entry reset if found */ - if (is_link_entry(curr)) { - curr = get_next_sdbt(curr); - if (sdbt) - free_page(sdbt); - - /* we are done if we reach the start */ - if ((unsigned long) curr == start) - break; - else - sdbt = (unsigned long) curr; - } else { - /* process SDB pointer */ - if (*curr) { - free_page(*curr); - curr++; - } - } - counter++; - } - cb->first_sdbt = 0; - } - return counter; -} - -static int start_sampling(int cpu) -{ - int rc; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - rc = smp_ctl_ssctl_enable_activate(cpu, interval); - if (rc) { - printk(KERN_INFO "hwsampler: CPU %d ssctl failed.\n", cpu); - goto start_exit; - } - - rc = -EINVAL; - if (!cb->qsi.es) { - printk(KERN_INFO "hwsampler: CPU %d ssctl not enabled.\n", cpu); - goto start_exit; - } - - if (!cb->qsi.cs) { - printk(KERN_INFO "hwsampler: CPU %d ssctl not active.\n", cpu); - goto start_exit; - } - - printk(KERN_INFO - "hwsampler: CPU %d, CPUMF Sampling started, interval %lu.\n", - cpu, interval); - - rc = 0; - -start_exit: - return rc; -} - -static int stop_sampling(int cpu) -{ - unsigned long v; - int rc; - struct hws_cpu_buffer *cb; - - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - - cb = &per_cpu(sampler_cpu_buffer, cpu); - if (!rc && !cb->qsi.es) - printk(KERN_INFO "hwsampler: CPU %d, already stopped.\n", cpu); - - rc = smp_ctl_ssctl_stop(cpu); - if (rc) { - printk(KERN_INFO "hwsampler: CPU %d, ssctl stop error %d.\n", - cpu, rc); - goto stop_exit; - } - - printk(KERN_INFO "hwsampler: CPU %d, CPUMF Sampling stopped.\n", cpu); - -stop_exit: - v = cb->req_alert; - if (v) - printk(KERN_ERR "hwsampler: CPU %d CPUMF Request alert," - " count=%lu.\n", cpu, v); - - v = cb->loss_of_sample_data; - if (v) - printk(KERN_ERR "hwsampler: CPU %d CPUMF Loss of sample data," - " count=%lu.\n", cpu, v); - - v = cb->invalid_entry_address; - if (v) - printk(KERN_ERR "hwsampler: CPU %d CPUMF Invalid entry address," - " count=%lu.\n", cpu, v); - - v = cb->incorrect_sdbt_entry; - if (v) - printk(KERN_ERR - "hwsampler: CPU %d CPUMF Incorrect SDBT address," - " count=%lu.\n", cpu, v); - - v = cb->sample_auth_change_alert; - if (v) - printk(KERN_ERR - "hwsampler: CPU %d CPUMF Sample authorization change," - " count=%lu.\n", cpu, v); - - return rc; -} - -static int check_hardware_prerequisites(void) -{ - if (!test_facility(68)) - return -EOPNOTSUPP; - return 0; -} -/* - * hws_oom_callback() - the OOM callback function - * - * In case the callback is invoked during memory allocation for the - * hw sampler, all obtained memory is deallocated and a flag is set - * so main sampler memory allocation can exit with a failure code. - * In case the callback is invoked during sampling the hw sampler - * is deactivated for all CPUs. - */ -static int hws_oom_callback(struct notifier_block *nfb, - unsigned long dummy, void *parm) -{ - unsigned long *freed; - int cpu; - struct hws_cpu_buffer *cb; - - freed = parm; - - mutex_lock(&hws_sem_oom); - - if (hws_state == HWS_DEALLOCATED) { - /* during memory allocation */ - if (oom_killer_was_active == 0) { - oom_killer_was_active = 1; - *freed += deallocate_sdbt(); - } - } else { - int i; - cpu = get_cpu(); - cb = &per_cpu(sampler_cpu_buffer, cpu); - - if (!cb->oom) { - for_each_online_cpu(i) { - smp_ctl_ssctl_deactivate(i); - cb->oom = 1; - } - cb->finish = 1; - - printk(KERN_INFO - "hwsampler: CPU %d, OOM notify during CPUMF Sampling.\n", - cpu); - } - } - - mutex_unlock(&hws_sem_oom); - - return NOTIFY_OK; -} - -static struct notifier_block hws_oom_notifier = { - .notifier_call = hws_oom_callback -}; - -static int hws_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - /* We do not have sampler space available for all possible CPUs. - All CPUs should be online when hw sampling is activated. */ - return (hws_state <= HWS_DEALLOCATED) ? NOTIFY_OK : NOTIFY_BAD; -} - -static struct notifier_block hws_cpu_notifier = { - .notifier_call = hws_cpu_callback -}; - -/** - * hwsampler_deactivate() - set hardware sampling temporarily inactive - * @cpu: specifies the CPU to be set inactive. - * - * Returns 0 on success, !0 on failure. - */ -int hwsampler_deactivate(unsigned int cpu) -{ - /* - * Deactivate hw sampling temporarily and flush the buffer - * by pushing all the pending samples to oprofile buffer. - * - * This function can be called under one of the following conditions: - * Memory unmap, task is exiting. - */ - int rc; - struct hws_cpu_buffer *cb; - - rc = 0; - mutex_lock(&hws_sem); - - cb = &per_cpu(sampler_cpu_buffer, cpu); - if (hws_state == HWS_STARTED) { - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - if (cb->qsi.cs) { - rc = smp_ctl_ssctl_deactivate(cpu); - if (rc) { - printk(KERN_INFO - "hwsampler: CPU %d, CPUMF Deactivation failed.\n", cpu); - cb->finish = 1; - hws_state = HWS_STOPPING; - } else { - hws_flush_all = 1; - /* Add work to queue to read pending samples.*/ - queue_work_on(cpu, hws_wq, &cb->worker); - } - } - } - mutex_unlock(&hws_sem); - - if (hws_wq) - flush_workqueue(hws_wq); - - return rc; -} - -/** - * hwsampler_activate() - activate/resume hardware sampling which was deactivated - * @cpu: specifies the CPU to be set active. - * - * Returns 0 on success, !0 on failure. - */ -int hwsampler_activate(unsigned int cpu) -{ - /* - * Re-activate hw sampling. This should be called in pair with - * hwsampler_deactivate(). - */ - int rc; - struct hws_cpu_buffer *cb; - - rc = 0; - mutex_lock(&hws_sem); - - cb = &per_cpu(sampler_cpu_buffer, cpu); - if (hws_state == HWS_STARTED) { - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - if (!cb->qsi.cs) { - hws_flush_all = 0; - rc = smp_ctl_ssctl_enable_activate(cpu, interval); - if (rc) { - printk(KERN_ERR - "CPU %d, CPUMF activate sampling failed.\n", - cpu); - } - } - } - - mutex_unlock(&hws_sem); - - return rc; -} - -static int check_qsi_on_setup(void) -{ - int rc; - unsigned int cpu; - struct hws_cpu_buffer *cb; - - for_each_online_cpu(cpu) { - cb = &per_cpu(sampler_cpu_buffer, cpu); - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - if (rc) - return -EOPNOTSUPP; - - if (!cb->qsi.as) { - printk(KERN_INFO "hwsampler: CPUMF sampling is not authorized.\n"); - return -EINVAL; - } - - if (cb->qsi.es) { - printk(KERN_WARNING "hwsampler: CPUMF is still enabled.\n"); - rc = smp_ctl_ssctl_stop(cpu); - if (rc) - return -EINVAL; - - printk(KERN_INFO - "CPU %d, CPUMF Sampling stopped now.\n", cpu); - } - } - return 0; -} - -static int check_qsi_on_start(void) -{ - unsigned int cpu; - int rc; - struct hws_cpu_buffer *cb; - - for_each_online_cpu(cpu) { - cb = &per_cpu(sampler_cpu_buffer, cpu); - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - - if (!cb->qsi.as) - return -EINVAL; - - if (cb->qsi.es) - return -EINVAL; - - if (cb->qsi.cs) - return -EINVAL; - } - return 0; -} - -static void worker_on_start(unsigned int cpu) -{ - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - cb->worker_entry = cb->first_sdbt; -} - -static int worker_check_error(unsigned int cpu, int ext_params) -{ - int rc; - unsigned long *sdbt; - struct hws_cpu_buffer *cb; - - rc = 0; - cb = &per_cpu(sampler_cpu_buffer, cpu); - sdbt = (unsigned long *) cb->worker_entry; - - if (!sdbt || !*sdbt) - return -EINVAL; - - if (ext_params & CPU_MF_INT_SF_PRA) - cb->req_alert++; - - if (ext_params & CPU_MF_INT_SF_LSDA) - cb->loss_of_sample_data++; - - if (ext_params & CPU_MF_INT_SF_IAE) { - cb->invalid_entry_address++; - rc = -EINVAL; - } - - if (ext_params & CPU_MF_INT_SF_ISE) { - cb->incorrect_sdbt_entry++; - rc = -EINVAL; - } - - if (ext_params & CPU_MF_INT_SF_SACA) { - cb->sample_auth_change_alert++; - rc = -EINVAL; - } - - return rc; -} - -static void worker_on_finish(unsigned int cpu) -{ - int rc, i; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - if (cb->finish) { - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - if (cb->qsi.es) { - printk(KERN_INFO - "hwsampler: CPU %d, CPUMF Stop/Deactivate sampling.\n", - cpu); - rc = smp_ctl_ssctl_stop(cpu); - if (rc) - printk(KERN_INFO - "hwsampler: CPU %d, CPUMF Deactivation failed.\n", - cpu); - - for_each_online_cpu(i) { - if (i == cpu) - continue; - if (!cb->finish) { - cb->finish = 1; - queue_work_on(i, hws_wq, - &cb->worker); - } - } - } - } -} - -static void worker_on_interrupt(unsigned int cpu) -{ - unsigned long *sdbt; - unsigned char done; - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - sdbt = (unsigned long *) cb->worker_entry; - - done = 0; - /* do not proceed if stop was entered, - * forget the buffers not yet processed */ - while (!done && !cb->stop_mode) { - unsigned long *trailer; - struct hws_trailer_entry *te; - unsigned long *dear = 0; - - trailer = trailer_entry_ptr(*sdbt); - /* leave loop if no more work to do */ - if (!(*trailer & SDB_TE_BUFFER_FULL_MASK)) { - done = 1; - if (!hws_flush_all) - continue; - } - - te = (struct hws_trailer_entry *)trailer; - cb->sample_overflow += te->overflow; - - add_samples_to_oprofile(cpu, sdbt, dear); - - /* reset trailer */ - xchg((unsigned char *) te, 0x40); - - /* advance to next sdb slot in current sdbt */ - sdbt++; - /* in case link bit is set use address w/o link bit */ - if (is_link_entry(sdbt)) - sdbt = get_next_sdbt(sdbt); - - cb->worker_entry = (unsigned long)sdbt; - } -} - -static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt, - unsigned long *dear) -{ - struct hws_basic_entry *sample_data_ptr; - unsigned long *trailer; - - trailer = trailer_entry_ptr(*sdbt); - if (dear) { - if (dear > trailer) - return; - trailer = dear; - } - - sample_data_ptr = (struct hws_basic_entry *)(*sdbt); - - while ((unsigned long *)sample_data_ptr < trailer) { - struct pt_regs *regs = NULL; - struct task_struct *tsk = NULL; - - /* - * Check sampling mode, 1 indicates basic (=customer) sampling - * mode. - */ - if (sample_data_ptr->def != 1) { - /* sample slot is not yet written */ - break; - } else { - /* make sure we don't use it twice, - * the next time the sampler will set it again */ - sample_data_ptr->def = 0; - } - - /* Get pt_regs. */ - if (sample_data_ptr->P == 1) { - /* userspace sample */ - unsigned int pid = sample_data_ptr->prim_asn; - if (!counter_config.user) - goto skip_sample; - rcu_read_lock(); - tsk = pid_task(find_vpid(pid), PIDTYPE_PID); - if (tsk) - regs = task_pt_regs(tsk); - rcu_read_unlock(); - } else { - /* kernelspace sample */ - if (!counter_config.kernel) - goto skip_sample; - regs = task_pt_regs(current); - } - - mutex_lock(&hws_sem); - oprofile_add_ext_hw_sample(sample_data_ptr->ia, regs, 0, - !sample_data_ptr->P, tsk); - mutex_unlock(&hws_sem); - skip_sample: - sample_data_ptr++; - } -} - -static void worker(struct work_struct *work) -{ - unsigned int cpu; - int ext_params; - struct hws_cpu_buffer *cb; - - cb = container_of(work, struct hws_cpu_buffer, worker); - cpu = smp_processor_id(); - ext_params = atomic_xchg(&cb->ext_params, 0); - - if (!cb->worker_entry) - worker_on_start(cpu); - - if (worker_check_error(cpu, ext_params)) - return; - - if (!cb->finish) - worker_on_interrupt(cpu); - - if (cb->finish) - worker_on_finish(cpu); -} - -/** - * hwsampler_allocate() - allocate memory for the hardware sampler - * @sdbt: number of SDBTs per online CPU (must be > 0) - * @sdb: number of SDBs per SDBT (minimum 1, maximum 511) - * - * Returns 0 on success, !0 on failure. - */ -int hwsampler_allocate(unsigned long sdbt, unsigned long sdb) -{ - int cpu, rc; - mutex_lock(&hws_sem); - - rc = -EINVAL; - if (hws_state != HWS_DEALLOCATED) - goto allocate_exit; - - if (sdbt < 1) - goto allocate_exit; - - if (sdb > MAX_NUM_SDB || sdb < MIN_NUM_SDB) - goto allocate_exit; - - num_sdbt = sdbt; - num_sdb = sdb; - - oom_killer_was_active = 0; - register_oom_notifier(&hws_oom_notifier); - - for_each_online_cpu(cpu) { - if (allocate_sdbt(cpu)) { - unregister_oom_notifier(&hws_oom_notifier); - goto allocate_error; - } - } - unregister_oom_notifier(&hws_oom_notifier); - if (oom_killer_was_active) - goto allocate_error; - - hws_state = HWS_STOPPED; - rc = 0; - -allocate_exit: - mutex_unlock(&hws_sem); - return rc; - -allocate_error: - rc = -ENOMEM; - printk(KERN_ERR "hwsampler: CPUMF Memory allocation failed.\n"); - goto allocate_exit; -} - -/** - * hwsampler_deallocate() - deallocate hardware sampler memory - * - * Returns 0 on success, !0 on failure. - */ -int hwsampler_deallocate(void) -{ - int rc; - - mutex_lock(&hws_sem); - - rc = -EINVAL; - if (hws_state != HWS_STOPPED) - goto deallocate_exit; - - irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); - hws_alert = 0; - deallocate_sdbt(); - - hws_state = HWS_DEALLOCATED; - rc = 0; - -deallocate_exit: - mutex_unlock(&hws_sem); - - return rc; -} - -unsigned long hwsampler_query_min_interval(void) -{ - return min_sampler_rate; -} - -unsigned long hwsampler_query_max_interval(void) -{ - return max_sampler_rate; -} - -unsigned long hwsampler_get_sample_overflow_count(unsigned int cpu) -{ - struct hws_cpu_buffer *cb; - - cb = &per_cpu(sampler_cpu_buffer, cpu); - - return cb->sample_overflow; -} - -int hwsampler_setup(void) -{ - int rc; - int cpu; - struct hws_cpu_buffer *cb; - - mutex_lock(&hws_sem); - - rc = -EINVAL; - if (hws_state) - goto setup_exit; - - hws_state = HWS_INIT; - - init_all_cpu_buffers(); - - rc = check_hardware_prerequisites(); - if (rc) - goto setup_exit; - - rc = check_qsi_on_setup(); - if (rc) - goto setup_exit; - - rc = -EINVAL; - hws_wq = create_workqueue("hwsampler"); - if (!hws_wq) - goto setup_exit; - - register_cpu_notifier(&hws_cpu_notifier); - - for_each_online_cpu(cpu) { - cb = &per_cpu(sampler_cpu_buffer, cpu); - INIT_WORK(&cb->worker, worker); - rc = smp_ctl_qsi(cpu); - WARN_ON(rc); - if (min_sampler_rate != cb->qsi.min_sampl_rate) { - if (min_sampler_rate) { - printk(KERN_WARNING - "hwsampler: different min sampler rate values.\n"); - if (min_sampler_rate < cb->qsi.min_sampl_rate) - min_sampler_rate = - cb->qsi.min_sampl_rate; - } else - min_sampler_rate = cb->qsi.min_sampl_rate; - } - if (max_sampler_rate != cb->qsi.max_sampl_rate) { - if (max_sampler_rate) { - printk(KERN_WARNING - "hwsampler: different max sampler rate values.\n"); - if (max_sampler_rate > cb->qsi.max_sampl_rate) - max_sampler_rate = - cb->qsi.max_sampl_rate; - } else - max_sampler_rate = cb->qsi.max_sampl_rate; - } - } - register_external_irq(EXT_IRQ_MEASURE_ALERT, hws_ext_handler); - - hws_state = HWS_DEALLOCATED; - rc = 0; - -setup_exit: - mutex_unlock(&hws_sem); - return rc; -} - -int hwsampler_shutdown(void) -{ - int rc; - - mutex_lock(&hws_sem); - - rc = -EINVAL; - if (hws_state == HWS_DEALLOCATED || hws_state == HWS_STOPPED) { - mutex_unlock(&hws_sem); - - if (hws_wq) - flush_workqueue(hws_wq); - - mutex_lock(&hws_sem); - - if (hws_state == HWS_STOPPED) { - irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); - hws_alert = 0; - deallocate_sdbt(); - } - if (hws_wq) { - destroy_workqueue(hws_wq); - hws_wq = NULL; - } - - unregister_external_irq(EXT_IRQ_MEASURE_ALERT, hws_ext_handler); - hws_state = HWS_INIT; - rc = 0; - } - mutex_unlock(&hws_sem); - - unregister_cpu_notifier(&hws_cpu_notifier); - - return rc; -} - -/** - * hwsampler_start_all() - start hardware sampling on all online CPUs - * @rate: specifies the used interval when samples are taken - * - * Returns 0 on success, !0 on failure. - */ -int hwsampler_start_all(unsigned long rate) -{ - int rc, cpu; - - mutex_lock(&hws_sem); - - hws_oom = 0; - - rc = -EINVAL; - if (hws_state != HWS_STOPPED) - goto start_all_exit; - - interval = rate; - - /* fail if rate is not valid */ - if (interval < min_sampler_rate || interval > max_sampler_rate) - goto start_all_exit; - - rc = check_qsi_on_start(); - if (rc) - goto start_all_exit; - - prepare_cpu_buffers(); - - for_each_online_cpu(cpu) { - rc = start_sampling(cpu); - if (rc) - break; - } - if (rc) { - for_each_online_cpu(cpu) { - stop_sampling(cpu); - } - goto start_all_exit; - } - hws_state = HWS_STARTED; - rc = 0; - -start_all_exit: - mutex_unlock(&hws_sem); - - if (rc) - return rc; - - register_oom_notifier(&hws_oom_notifier); - hws_oom = 1; - hws_flush_all = 0; - /* now let them in, 1407 CPUMF external interrupts */ - hws_alert = 1; - irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); - - return 0; -} - -/** - * hwsampler_stop_all() - stop hardware sampling on all online CPUs - * - * Returns 0 on success, !0 on failure. - */ -int hwsampler_stop_all(void) -{ - int tmp_rc, rc, cpu; - struct hws_cpu_buffer *cb; - - mutex_lock(&hws_sem); - - rc = 0; - if (hws_state == HWS_INIT) { - mutex_unlock(&hws_sem); - return 0; - } - hws_state = HWS_STOPPING; - mutex_unlock(&hws_sem); - - for_each_online_cpu(cpu) { - cb = &per_cpu(sampler_cpu_buffer, cpu); - cb->stop_mode = 1; - tmp_rc = stop_sampling(cpu); - if (tmp_rc) - rc = tmp_rc; - } - - if (hws_wq) - flush_workqueue(hws_wq); - - mutex_lock(&hws_sem); - if (hws_oom) { - unregister_oom_notifier(&hws_oom_notifier); - hws_oom = 0; - } - hws_state = HWS_STOPPED; - mutex_unlock(&hws_sem); - - return rc; -} diff --git a/arch/s390/oprofile/hwsampler.h b/arch/s390/oprofile/hwsampler.h deleted file mode 100644 index a483d06f2fa7..000000000000 --- a/arch/s390/oprofile/hwsampler.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * CPUMF HW sampler functions and internal structures - * - * Copyright IBM Corp. 2010 - * Author(s): Heinz Graalfs - */ - -#ifndef HWSAMPLER_H_ -#define HWSAMPLER_H_ - -#include -#include - -struct hws_ssctl_request_block /* SET SAMPLING CONTROLS req block */ -{ /* bytes 0 - 7 Bit(s) */ - unsigned int s:1; /* 0: maximum buffer indicator */ - unsigned int h:1; /* 1: part. level reserved for VM use*/ - unsigned long b2_53:52; /* 2-53: zeros */ - unsigned int es:1; /* 54: sampling enable control */ - unsigned int b55_61:7; /* 55-61: - zeros */ - unsigned int cs:1; /* 62: sampling activation control */ - unsigned int b63:1; /* 63: zero */ - unsigned long interval; /* 8-15: sampling interval */ - unsigned long tear; /* 16-23: TEAR contents */ - unsigned long dear; /* 24-31: DEAR contents */ - /* 32-63: */ - unsigned long rsvrd1; /* reserved */ - unsigned long rsvrd2; /* reserved */ - unsigned long rsvrd3; /* reserved */ - unsigned long rsvrd4; /* reserved */ -}; - -struct hws_cpu_buffer { - unsigned long first_sdbt; /* @ of 1st SDB-Table for this CP*/ - unsigned long worker_entry; - unsigned long sample_overflow; /* taken from SDB ... */ - struct hws_qsi_info_block qsi; - struct hws_ssctl_request_block ssctl; - struct work_struct worker; - atomic_t ext_params; - unsigned long req_alert; - unsigned long loss_of_sample_data; - unsigned long invalid_entry_address; - unsigned long incorrect_sdbt_entry; - unsigned long sample_auth_change_alert; - unsigned int finish:1; - unsigned int oom:1; - unsigned int stop_mode:1; -}; - -int hwsampler_setup(void); -int hwsampler_shutdown(void); -int hwsampler_allocate(unsigned long sdbt, unsigned long sdb); -int hwsampler_deallocate(void); -unsigned long hwsampler_query_min_interval(void); -unsigned long hwsampler_query_max_interval(void); -int hwsampler_start_all(unsigned long interval); -int hwsampler_stop_all(void); -int hwsampler_deactivate(unsigned int cpu); -int hwsampler_activate(unsigned int cpu); -unsigned long hwsampler_get_sample_overflow_count(unsigned int cpu); - -#endif /*HWSAMPLER_H_*/ diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 791935a65800..16f4c3960b87 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c @@ -10,488 +10,8 @@ */ #include -#include #include -#include -#include -#include #include -#include - -#include "../../../drivers/oprofile/oprof.h" - -#include "hwsampler.h" -#include "op_counter.h" - -#define DEFAULT_INTERVAL 4127518 - -#define DEFAULT_SDBT_BLOCKS 1 -#define DEFAULT_SDB_BLOCKS 511 - -static unsigned long oprofile_hw_interval = DEFAULT_INTERVAL; -static unsigned long oprofile_min_interval; -static unsigned long oprofile_max_interval; - -static unsigned long oprofile_sdbt_blocks = DEFAULT_SDBT_BLOCKS; -static unsigned long oprofile_sdb_blocks = DEFAULT_SDB_BLOCKS; - -static int hwsampler_enabled; -static int hwsampler_running; /* start_mutex must be held to change */ -static int hwsampler_available; - -static struct oprofile_operations timer_ops; - -struct op_counter_config counter_config; - -enum __force_cpu_type { - reserved = 0, /* do not force */ - timer, -}; -static int force_cpu_type; - -static int set_cpu_type(const char *str, struct kernel_param *kp) -{ - if (!strcmp(str, "timer")) { - force_cpu_type = timer; - printk(KERN_INFO "oprofile: forcing timer to be returned " - "as cpu type\n"); - } else { - force_cpu_type = 0; - } - - return 0; -} -module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0); -MODULE_PARM_DESC(cpu_type, "Force legacy basic mode sampling" - "(report cpu_type \"timer\""); - -static int __oprofile_hwsampler_start(void) -{ - int retval; - - retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks); - if (retval) - return retval; - - retval = hwsampler_start_all(oprofile_hw_interval); - if (retval) - hwsampler_deallocate(); - - return retval; -} - -static int oprofile_hwsampler_start(void) -{ - int retval; - - hwsampler_running = hwsampler_enabled; - - if (!hwsampler_running) - return timer_ops.start(); - - retval = perf_reserve_sampling(); - if (retval) - return retval; - - retval = __oprofile_hwsampler_start(); - if (retval) - perf_release_sampling(); - - return retval; -} - -static void oprofile_hwsampler_stop(void) -{ - if (!hwsampler_running) { - timer_ops.stop(); - return; - } - - hwsampler_stop_all(); - hwsampler_deallocate(); - perf_release_sampling(); - return; -} - -/* - * File ops used for: - * /dev/oprofile/0/enabled - * /dev/oprofile/hwsampling/hwsampler (cpu_type = timer) - */ - -static ssize_t hwsampler_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(hwsampler_enabled, buf, count, offset); -} - -static ssize_t hwsampler_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - if (val != 0 && val != 1) - return -EINVAL; - - if (oprofile_started) - /* - * save to do without locking as we set - * hwsampler_running in start() when start_mutex is - * held - */ - return -EBUSY; - - hwsampler_enabled = val; - - return count; -} - -static const struct file_operations hwsampler_fops = { - .read = hwsampler_read, - .write = hwsampler_write, -}; - -/* - * File ops used for: - * /dev/oprofile/0/count - * /dev/oprofile/hwsampling/hw_interval (cpu_type = timer) - * - * Make sure that the value is within the hardware range. - */ - -static ssize_t hw_interval_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(oprofile_hw_interval, buf, - count, offset); -} - -static ssize_t hw_interval_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - if (val < oprofile_min_interval) - oprofile_hw_interval = oprofile_min_interval; - else if (val > oprofile_max_interval) - oprofile_hw_interval = oprofile_max_interval; - else - oprofile_hw_interval = val; - - return count; -} - -static const struct file_operations hw_interval_fops = { - .read = hw_interval_read, - .write = hw_interval_write, -}; - -/* - * File ops used for: - * /dev/oprofile/0/event - * Only a single event with number 0 is supported with this counter. - * - * /dev/oprofile/0/unit_mask - * This is a dummy file needed by the user space tools. - * No value other than 0 is accepted or returned. - */ - -static ssize_t hwsampler_zero_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(0, buf, count, offset); -} - -static ssize_t hwsampler_zero_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - if (val != 0) - return -EINVAL; - return count; -} - -static const struct file_operations zero_fops = { - .read = hwsampler_zero_read, - .write = hwsampler_zero_write, -}; - -/* /dev/oprofile/0/kernel file ops. */ - -static ssize_t hwsampler_kernel_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(counter_config.kernel, - buf, count, offset); -} - -static ssize_t hwsampler_kernel_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - if (val != 0 && val != 1) - return -EINVAL; - - counter_config.kernel = val; - - return count; -} - -static const struct file_operations kernel_fops = { - .read = hwsampler_kernel_read, - .write = hwsampler_kernel_write, -}; - -/* /dev/oprofile/0/user file ops. */ - -static ssize_t hwsampler_user_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(counter_config.user, - buf, count, offset); -} - -static ssize_t hwsampler_user_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - if (val != 0 && val != 1) - return -EINVAL; - - counter_config.user = val; - - return count; -} - -static const struct file_operations user_fops = { - .read = hwsampler_user_read, - .write = hwsampler_user_write, -}; - - -/* - * File ops used for: /dev/oprofile/timer/enabled - * The value always has to be the inverted value of hwsampler_enabled. So - * no separate variable is created. That way we do not need locking. - */ - -static ssize_t timer_enabled_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(!hwsampler_enabled, buf, count, offset); -} - -static ssize_t timer_enabled_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - if (val != 0 && val != 1) - return -EINVAL; - - /* Timer cannot be disabled without having hardware sampling. */ - if (val == 0 && !hwsampler_available) - return -EINVAL; - - if (oprofile_started) - /* - * save to do without locking as we set - * hwsampler_running in start() when start_mutex is - * held - */ - return -EBUSY; - - hwsampler_enabled = !val; - - return count; -} - -static const struct file_operations timer_enabled_fops = { - .read = timer_enabled_read, - .write = timer_enabled_write, -}; - - -static int oprofile_create_hwsampling_files(struct dentry *root) -{ - struct dentry *dir; - - dir = oprofilefs_mkdir(root, "timer"); - if (!dir) - return -EINVAL; - - oprofilefs_create_file(dir, "enabled", &timer_enabled_fops); - - if (!hwsampler_available) - return 0; - - /* reinitialize default values */ - hwsampler_enabled = 1; - counter_config.kernel = 1; - counter_config.user = 1; - - if (!force_cpu_type) { - /* - * Create the counter file system. A single virtual - * counter is created which can be used to - * enable/disable hardware sampling dynamically from - * user space. The user space will configure a single - * counter with a single event. The value of 'event' - * and 'unit_mask' are not evaluated by the kernel code - * and can only be set to 0. - */ - - dir = oprofilefs_mkdir(root, "0"); - if (!dir) - return -EINVAL; - - oprofilefs_create_file(dir, "enabled", &hwsampler_fops); - oprofilefs_create_file(dir, "event", &zero_fops); - oprofilefs_create_file(dir, "count", &hw_interval_fops); - oprofilefs_create_file(dir, "unit_mask", &zero_fops); - oprofilefs_create_file(dir, "kernel", &kernel_fops); - oprofilefs_create_file(dir, "user", &user_fops); - oprofilefs_create_ulong(dir, "hw_sdbt_blocks", - &oprofile_sdbt_blocks); - - } else { - /* - * Hardware sampling can be used but the cpu_type is - * forced to timer in order to deal with legacy user - * space tools. The /dev/oprofile/hwsampling fs is - * provided in that case. - */ - dir = oprofilefs_mkdir(root, "hwsampling"); - if (!dir) - return -EINVAL; - - oprofilefs_create_file(dir, "hwsampler", - &hwsampler_fops); - oprofilefs_create_file(dir, "hw_interval", - &hw_interval_fops); - oprofilefs_create_ro_ulong(dir, "hw_min_interval", - &oprofile_min_interval); - oprofilefs_create_ro_ulong(dir, "hw_max_interval", - &oprofile_max_interval); - oprofilefs_create_ulong(dir, "hw_sdbt_blocks", - &oprofile_sdbt_blocks); - } - return 0; -} - -static int oprofile_hwsampler_init(struct oprofile_operations *ops) -{ - /* - * Initialize the timer mode infrastructure as well in order - * to be able to switch back dynamically. oprofile_timer_init - * is not supposed to fail. - */ - if (oprofile_timer_init(ops)) - BUG(); - - memcpy(&timer_ops, ops, sizeof(timer_ops)); - ops->create_files = oprofile_create_hwsampling_files; - - /* - * If the user space tools do not support newer cpu types, - * the force_cpu_type module parameter - * can be used to always return \"timer\" as cpu type. - */ - if (force_cpu_type != timer) { - struct cpuid id; - - get_cpu_id (&id); - - switch (id.machine) { - case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break; - case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break; - case 0x2827: case 0x2828: ops->cpu_type = "s390/zEC12"; break; - case 0x2964: case 0x2965: ops->cpu_type = "s390/z13"; break; - default: return -ENODEV; - } - } - - if (hwsampler_setup()) - return -ENODEV; - - /* - * Query the range for the sampling interval from the - * hardware. - */ - oprofile_min_interval = hwsampler_query_min_interval(); - if (oprofile_min_interval == 0) - return -ENODEV; - oprofile_max_interval = hwsampler_query_max_interval(); - if (oprofile_max_interval == 0) - return -ENODEV; - - /* The initial value should be sane */ - if (oprofile_hw_interval < oprofile_min_interval) - oprofile_hw_interval = oprofile_min_interval; - if (oprofile_hw_interval > oprofile_max_interval) - oprofile_hw_interval = oprofile_max_interval; - - printk(KERN_INFO "oprofile: System z hardware sampling " - "facility found.\n"); - - ops->start = oprofile_hwsampler_start; - ops->stop = oprofile_hwsampler_stop; - - return 0; -} - -static void oprofile_hwsampler_exit(void) -{ - hwsampler_shutdown(); -} static int __s390_backtrace(void *data, unsigned long address) { @@ -514,18 +34,9 @@ static void s390_backtrace(struct pt_regs *regs, unsigned int depth) int __init oprofile_arch_init(struct oprofile_operations *ops) { ops->backtrace = s390_backtrace; - - /* - * -ENODEV is not reported to the caller. The module itself - * will use the timer mode sampling as fallback and this is - * always available. - */ - hwsampler_available = oprofile_hwsampler_init(ops) == 0; - return 0; } void oprofile_arch_exit(void) { - oprofile_hwsampler_exit(); } diff --git a/arch/s390/oprofile/op_counter.h b/arch/s390/oprofile/op_counter.h deleted file mode 100644 index 61b2531eef17..000000000000 --- a/arch/s390/oprofile/op_counter.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright IBM Corp. 2011 - * Author(s): Andreas Krebbel (krebbel@linux.vnet.ibm.com) - * - * @remark Copyright 2011 OProfile authors - */ - -#ifndef OP_COUNTER_H -#define OP_COUNTER_H - -struct op_counter_config { - /* `enabled' maps to the hwsampler_file variable. */ - /* `count' maps to the oprofile_hw_interval variable. */ - /* `event' and `unit_mask' are unused. */ - unsigned long kernel; - unsigned long user; -}; - -extern struct op_counter_config counter_config; - -#endif /* OP_COUNTER_H */ -- cgit v1.3-14-g43fede From 85889876ca37d67c20d14e444b111c0b81744b3e Mon Sep 17 00:00:00 2001 From: Huang Tao Date: Thu, 16 Jun 2016 15:54:27 +0200 Subject: dt-bindings: Document rk3399 rk-timer bindings Add a compatible string for rk3399 SoC because the timer is slightly different from the older SoCs. So rename the file name from rockchip,rk3288-timer.txt to rockchip,rk-timer.txt and clarify rockchip,rk3288-timer supported SoCs. Signed-off-by: Huang Tao Cc: Rob Herring Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Heiko Stuebner Signed-off-by: Caesar Wang Acked-by: Rob Herring Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/timer/rockchip,rk-timer.txt | 20 ++++++++++++++++++++ .../bindings/timer/rockchip,rk3288-timer.txt | 18 ------------------ 2 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt delete mode 100644 Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt new file mode 100644 index 000000000000..a41b184d5538 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt @@ -0,0 +1,20 @@ +Rockchip rk timer + +Required properties: +- compatible: shall be one of: + "rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368 + "rockchip,rk3399-timer" - for rk3399 +- reg: base address of the timer register starting with TIMERS CONTROL register +- interrupts: should contain the interrupts for Timer0 +- clocks : must contain an entry for each entry in clock-names +- clock-names : must include the following entries: + "timer", "pclk" + +Example: + timer: timer@ff810000 { + compatible = "rockchip,rk3288-timer"; + reg = <0xff810000 0x20>; + interrupts = ; + clocks = <&xin24m>, <&cru PCLK_TIMER>; + clock-names = "timer", "pclk"; + }; diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt deleted file mode 100644 index 87f0b0042bae..000000000000 --- a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt +++ /dev/null @@ -1,18 +0,0 @@ -Rockchip rk3288 timer - -Required properties: -- compatible: shall be "rockchip,rk3288-timer" -- reg: base address of the timer register starting with TIMERS CONTROL register -- interrupts: should contain the interrupts for Timer0 -- clocks : must contain an entry for each entry in clock-names -- clock-names : must include the following entries: - "timer", "pclk" - -Example: - timer: timer@ff810000 { - compatible = "rockchip,rk3288-timer"; - reg = <0xff810000 0x20>; - interrupts = ; - clocks = <&xin24m>, <&cru PCLK_TIMER>; - clock-names = "timer", "pclk"; - }; -- cgit v1.3-14-g43fede From 43e88c8a73f5896b964183d503d9bf892a551e25 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2016 12:13:27 +0200 Subject: dt-bindings: clocksource: Add Oxford Semiconductor RPS Timer bindings Add DT bindings for the Oxford Semiconductor RPS dual Timer. Signed-off-by: Neil Armstrong Signed-off-by: Daniel Lezcano Acked-by: Rob Herring --- .../devicetree/bindings/timer/oxsemi,rps-timer.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt b/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt new file mode 100644 index 000000000000..3ca89cd1caef --- /dev/null +++ b/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt @@ -0,0 +1,17 @@ +Oxford Semiconductor OXNAS SoCs Family RPS Timer +================================================ + +Required properties: +- compatible: Should be "oxsemi,ox810se-rps-timer" +- reg : Specifies base physical address and size of the registers. +- interrupts : The interrupts of the two timers +- clocks : The phandle of the timer clock source + +example: + +timer0: timer@200 { + compatible = "oxsemi,ox810se-rps-timer"; + reg = <0x200 0x40>; + clocks = <&rpsclk>; + interrupts = <4 5>; +}; -- cgit v1.3-14-g43fede From 46fd5c6b3059462131caa4d52691c9c5666c3223 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 27 Jun 2016 17:30:13 +0100 Subject: clocksource/drivers/arm_arch_timer: Control the evtstrm via the cmdline Disabling the eventstream can be useful for both remotely debugging a deployed production system and development of code using WFE-based polling loops. Whilst this can currently be controlled via a Kconfig option (CONFIG_ARM_ARCH_TIMER_EVTSTREAM), it's often desirable to toggle the feature on the command line, so this patch adds a new command-line option ("clocksource.arm_arch_timer.evtstrm") to do just that. The default behaviour is determined based on CONFIG_ARM_ARCH_TIMER_EVTSTREAM. Cc: Marc Zyngier Cc: Mark Rutland Signed-off-by: Will Deacon Signed-off-by: Daniel Lezcano --- Documentation/kernel-parameters.txt | 8 ++++++++ drivers/clocksource/Kconfig | 12 +++++++----- drivers/clocksource/arm_arch_timer.c | 10 +++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..2c92f1df7c69 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -687,6 +687,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. [SPARC64] tick [X86-64] hpet,tsc + clocksource.arm_arch_timer.evtstrm= + [ARM,ARM64] + Format: + Enable/disable the eventstream feature of the ARM + architected timer so that code using WFE-based polling + loops can be debugged more effectively on production + systems. + clearcpuid=BITNUM [X86] Disable CPUID feature X for the kernel. See arch/x86/include/asm/cpufeatures.h for the valid bit diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 7acdf3d735ac..567788664723 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -288,14 +288,16 @@ config ARM_ARCH_TIMER select CLKSRC_ACPI if ACPI config ARM_ARCH_TIMER_EVTSTREAM - bool "Support for ARM architected timer event stream generation" + bool "Enable ARM architected timer event stream generation by default" default y if ARM_ARCH_TIMER depends on ARM_ARCH_TIMER help - This option enables support for event stream generation based on - the ARM architected timer. It is used for waking up CPUs executing - the wfe instruction at a frequency represented as a power-of-2 - divisor of the clock rate. + This option enables support by default for event stream generation + based on the ARM architected timer. It is used for waking up CPUs + executing the wfe instruction at a frequency represented as a + power-of-2 divisor of the clock rate. The behaviour can also be + overridden on the command line using the + clocksource.arm_arch_timer.evtstream parameter. The main use of the event stream is wfe-based timeouts of userspace locking implementations. It might also be useful for imposing timeout on wfe to safeguard against any programming errors in case an expected diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 9e33309ad2ea..5effd3027319 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -79,6 +79,14 @@ static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; static bool arch_timer_c3stop; static bool arch_timer_mem_use_virtual; +static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); + +static int __init early_evtstrm_cfg(char *buf) +{ + return strtobool(buf, &evtstrm_enable); +} +early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg); + /* * Architected system timer support. */ @@ -372,7 +380,7 @@ static int arch_timer_setup(struct clock_event_device *clk) enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0); arch_counter_set_user_access(); - if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM)) + if (evtstrm_enable) arch_timer_configure_evtstream(); return 0; -- cgit v1.3-14-g43fede From 70523e639bf8ca09b3357371c3546cee55c06351 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Fri, 24 Jun 2016 15:16:24 +0200 Subject: drivers: net: stmmac: reworking the PCS code. The 3.xx and 4.xx synopsys gmacs have a very similar PCS embedded module and they share almost the same registers: for example: AN_Control, AN_Status, AN_Advertisement, AN_Link_Partner_Ability, AN_Expansion, TBI_Extended_Status. Just the RGMII/SMII Control/Status register differs. So This patch aims to reorganize and enhance the PCS support. It removes the existent support from the dwmac1000/dwmac4_core.c moving basic PCS functions inside a new file called: stmmac_pcs.h. The patch also reviews the available APIs to be better shared among different hardware and easily enhanced to support new features. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- Documentation/networking/stmmac.txt | 1 + drivers/net/ethernet/stmicro/stmmac/common.h | 16 ++- drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 56 +++----- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 110 +++++++------- drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 34 +++-- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 73 ++++++---- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 54 ++++--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 12 +- drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h | 159 +++++++++++++++++++++ 9 files changed, 350 insertions(+), 165 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h (limited to 'Documentation') diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index 671fe3dd56d3..e226f8925c9e 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -285,6 +285,7 @@ Please see the following document: o mmc_core.c/mmc.h: Management MAC Counters; o stmmac_hwtstamp.c: HW timestamp support for PTP; o stmmac_ptp.c: PTP 1588 clock; + o stmmac_pcs.h: Physical Coding Sublayer common implementation; o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c for STMicroelectronics SoCs. diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index fc60368df2e7..86eba2a7bbea 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -232,6 +232,11 @@ struct stmmac_extra_stats { #define DMA_HW_FEAT_ACTPHYIF 0x70000000 /* Active/selected PHY iface */ #define DEFAULT_DMA_PBL 8 +/* PCS status and mask defines */ +#define PCS_ANE_IRQ BIT(2) /* PCS Auto-Negotiation */ +#define PCS_LINK_IRQ BIT(1) /* PCS Link */ +#define PCS_RGSMIIIS_IRQ BIT(0) /* RGMII or SMII Interrupt */ + /* Max/Min RI Watchdog Timer count value */ #define MAX_DMA_RIWT 0xff #define MIN_DMA_RIWT 0x20 @@ -272,9 +277,6 @@ enum dma_irq_status { #define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 2) #define CORE_IRQ_RX_PATH_EXIT_LPI_MODE (1 << 3) -#define CORE_PCS_ANE_COMPLETE (1 << 5) -#define CORE_PCS_LINK_STATUS (1 << 6) -#define CORE_RGMII_IRQ (1 << 7) #define CORE_IRQ_MTL_RX_OVERFLOW BIT(8) /* Physical Coding Sublayer */ @@ -469,9 +471,12 @@ struct stmmac_ops { void (*reset_eee_mode)(struct mac_device_info *hw); void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw); void (*set_eee_pls)(struct mac_device_info *hw, int link); - void (*ctrl_ane)(struct mac_device_info *hw, bool restart); - void (*get_adv)(struct mac_device_info *hw, struct rgmii_adv *adv); void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x); + /* PCS calls */ + void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral, + bool loopback); + void (*pcs_rane)(void __iomem *ioaddr, bool restart); + void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv); }; /* PTP and HW Timer helpers */ @@ -546,6 +551,7 @@ void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable); void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); + extern const struct stmmac_mode_ops ring_mode_ops; extern const struct stmmac_mode_ops chain_mode_ops; extern const struct stmmac_desc_ops dwmac4_desc_ops; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index b0593a4268ee..e67136038e55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -46,9 +46,6 @@ enum dwmac1000_irq_status { mmc_rx_irq = 0x0020, mmc_irq = 0x0010, pmt_irq = 0x0008, - pcs_ane_irq = 0x0004, - pcs_link_irq = 0x0002, - rgmii_irq = 0x0001, }; #define GMAC_INT_MASK 0x0000003c /* interrupt mask register */ @@ -90,42 +87,23 @@ enum power_event { (reg * 8)) #define GMAC_MAX_PERFECT_ADDRESSES 1 -/* PCS registers (AN/TBI/SGMII/RGMII) offset */ -#define GMAC_AN_CTRL 0x000000c0 /* AN control */ -#define GMAC_AN_STATUS 0x000000c4 /* AN status */ -#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */ -#define GMAC_ANE_LPA 0x000000cc /* Auto-Neg. link partener ability */ -#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */ -#define GMAC_TBI 0x000000d4 /* TBI extend status */ -#define GMAC_S_R_GMII 0x000000d8 /* SGMII RGMII status */ - -/* AN Configuration defines */ -#define GMAC_AN_CTRL_RAN 0x00000200 /* Restart Auto-Negotiation */ -#define GMAC_AN_CTRL_ANE 0x00001000 /* Auto-Negotiation Enable */ -#define GMAC_AN_CTRL_ELE 0x00004000 /* External Loopback Enable */ -#define GMAC_AN_CTRL_ECD 0x00010000 /* Enable Comma Detect */ -#define GMAC_AN_CTRL_LR 0x00020000 /* Lock to Reference */ -#define GMAC_AN_CTRL_SGMRAL 0x00040000 /* SGMII RAL Control */ - -/* AN Status defines */ -#define GMAC_AN_STATUS_LS 0x00000004 /* Link Status 0:down 1:up */ -#define GMAC_AN_STATUS_ANA 0x00000008 /* Auto-Negotiation Ability */ -#define GMAC_AN_STATUS_ANC 0x00000020 /* Auto-Negotiation Complete */ -#define GMAC_AN_STATUS_ES 0x00000100 /* Extended Status */ - -/* Register 54 (SGMII/RGMII status register) */ -#define GMAC_S_R_GMII_LINK 0x8 -#define GMAC_S_R_GMII_SPEED 0x5 -#define GMAC_S_R_GMII_SPEED_SHIFT 0x1 -#define GMAC_S_R_GMII_MODE 0x1 -#define GMAC_S_R_GMII_SPEED_125 2 -#define GMAC_S_R_GMII_SPEED_25 1 - -/* Common ADV and LPA defines */ -#define GMAC_ANE_FD (1 << 5) -#define GMAC_ANE_HD (1 << 6) -#define GMAC_ANE_PSE (3 << 7) -#define GMAC_ANE_PSE_SHIFT 7 +#define GMAC_PCS_BASE 0x000000c0 /* PCS register base */ +#define GMAC_RGSMIIIS 0x000000d8 /* RGMII/SMII status */ + +/* SGMII/RGMII status register */ +#define GMAC_RGSMIIIS_LNKMODE BIT(0) +#define GMAC_RGSMIIIS_SPEED GENMASK(2, 1) +#define GMAC_RGSMIIIS_SPEED_SHIFT 1 +#define GMAC_RGSMIIIS_LNKSTS BIT(3) +#define GMAC_RGSMIIIS_JABTO BIT(4) +#define GMAC_RGSMIIIS_FALSECARDET BIT(5) +#define GMAC_RGSMIIIS_SMIDRXS BIT(16) +/* LNKMOD */ +#define GMAC_RGSMIIIS_LNKMOD_MASK 0x1 +/* LNKSPEED */ +#define GMAC_RGSMIIIS_SPEED_125 0x2 +#define GMAC_RGSMIIIS_SPEED_25 0x1 +#define GMAC_RGSMIIIS_SPEED_2_5 0x0 /* GMAC Configuration defines */ #define GMAC_CONTROL_2K 0x08000000 /* IEEE 802.3as 2K packets */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index fb1eb578e34e..9772a43c27ef 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -30,6 +30,7 @@ #include #include #include +#include "stmmac_pcs.h" #include "dwmac1000.h" static void dwmac1000_core_init(struct mac_device_info *hw, int mtu) @@ -241,6 +242,39 @@ static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode) writel(pmt, ioaddr + GMAC_PMT); } +/* RGMII or SMII interface */ +static void dwmac1000_rgsmii(void __iomem *ioaddr, struct stmmac_extra_stats *x) +{ + u32 status; + + status = readl(ioaddr + GMAC_RGSMIIIS); + x->irq_rgmii_n++; + + /* Check the link status */ + if (status & GMAC_RGSMIIIS_LNKSTS) { + int speed_value; + + x->pcs_link = 1; + + speed_value = ((status & GMAC_RGSMIIIS_SPEED) >> + GMAC_RGSMIIIS_SPEED_SHIFT); + if (speed_value == GMAC_RGSMIIIS_SPEED_125) + x->pcs_speed = SPEED_1000; + else if (speed_value == GMAC_RGSMIIIS_SPEED_25) + x->pcs_speed = SPEED_100; + else + x->pcs_speed = SPEED_10; + + x->pcs_duplex = (status & GMAC_RGSMIIIS_LNKMOD_MASK); + + pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed, + x->pcs_duplex ? "Full" : "Half"); + } else { + x->pcs_link = 0; + pr_info("Link is Down\n"); + } +} + static int dwmac1000_irq_status(struct mac_device_info *hw, struct stmmac_extra_stats *x) { @@ -260,6 +294,7 @@ static int dwmac1000_irq_status(struct mac_device_info *hw, readl(ioaddr + GMAC_PMT); x->irq_receive_pmt_irq_n++; } + /* MAC trx/rx EEE LPI entry/exit interrupts */ if (intr_status & lpiis_irq) { /* Clean LPI interrupt by reading the Reg 12 */ @@ -275,36 +310,10 @@ static int dwmac1000_irq_status(struct mac_device_info *hw, x->irq_rx_path_exit_lpi_mode_n++; } - if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) { - readl(ioaddr + GMAC_AN_STATUS); - x->irq_pcs_ane_n++; - } - if (intr_status & rgmii_irq) { - u32 status = readl(ioaddr + GMAC_S_R_GMII); - x->irq_rgmii_n++; - - /* Save and dump the link status. */ - if (status & GMAC_S_R_GMII_LINK) { - int speed_value = (status & GMAC_S_R_GMII_SPEED) >> - GMAC_S_R_GMII_SPEED_SHIFT; - x->pcs_duplex = (status & GMAC_S_R_GMII_MODE); - - if (speed_value == GMAC_S_R_GMII_SPEED_125) - x->pcs_speed = SPEED_1000; - else if (speed_value == GMAC_S_R_GMII_SPEED_25) - x->pcs_speed = SPEED_100; - else - x->pcs_speed = SPEED_10; - - x->pcs_link = 1; - pr_debug("%s: Link is Up - %d/%s\n", __func__, - (int)x->pcs_speed, - x->pcs_duplex ? "Full" : "Half"); - } else { - x->pcs_link = 0; - pr_debug("%s: Link is Down\n", __func__); - } - } + dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); + + if (intr_status & PCS_RGSMIIIS_IRQ) + dwmac1000_rgsmii(ioaddr, x); return ret; } @@ -363,38 +372,20 @@ static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw) writel(value, ioaddr + LPI_TIMER_CTRL); } -static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart) +static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral, + bool loopback) { - void __iomem *ioaddr = hw->pcsr; - /* auto negotiation enable and External Loopback enable */ - u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE; - - if (restart) - value |= GMAC_AN_CTRL_RAN; - - writel(value, ioaddr + GMAC_AN_CTRL); + dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback); } -static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv) +static void dwmac1000_rane(void __iomem *ioaddr, bool restart) { - void __iomem *ioaddr = hw->pcsr; - u32 value = readl(ioaddr + GMAC_ANE_ADV); - - if (value & GMAC_ANE_FD) - adv->duplex = DUPLEX_FULL; - if (value & GMAC_ANE_HD) - adv->duplex |= DUPLEX_HALF; - - adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; - - value = readl(ioaddr + GMAC_ANE_LPA); - - if (value & GMAC_ANE_FD) - adv->lp_duplex = DUPLEX_FULL; - if (value & GMAC_ANE_HD) - adv->lp_duplex = DUPLEX_HALF; + dwmac_rane(ioaddr, GMAC_PCS_BASE, restart); +} - adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; +static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv) +{ + dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv); } static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x) @@ -485,9 +476,10 @@ static const struct stmmac_ops dwmac1000_ops = { .reset_eee_mode = dwmac1000_reset_eee_mode, .set_eee_timer = dwmac1000_set_eee_timer, .set_eee_pls = dwmac1000_set_eee_pls, - .ctrl_ane = dwmac1000_ctrl_ane, - .get_adv = dwmac1000_get_adv, .debug = dwmac1000_debug, + .pcs_ctrl_ane = dwmac1000_ctrl_ane, + .pcs_rane = dwmac1000_rane, + .pcs_get_adv_lp = dwmac1000_get_adv_lp, }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index bc50952a18e7..227fa20d10c1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -24,10 +24,8 @@ #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4) #define GMAC_INT_STATUS 0x000000b0 #define GMAC_INT_EN 0x000000b4 -#define GMAC_AN_CTRL 0x000000e0 -#define GMAC_AN_STATUS 0x000000e4 -#define GMAC_AN_ADV 0x000000e8 -#define GMAC_AN_LPA 0x000000ec +#define GMAC_PCS_BASE 0x000000e0 +#define GMAC_PHYIF_CONTROL_STATUS 0x000000f8 #define GMAC_PMT 0x000000c0 #define GMAC_VERSION 0x00000110 #define GMAC_DEBUG 0x00000114 @@ -64,19 +62,8 @@ enum dwmac4_irq_status { mmc_rx_irq = 0x00000200, mmc_irq = 0x00000100, pmt_irq = 0x00000010, - pcs_ane_irq = 0x00000004, - pcs_link_irq = 0x00000002, }; -/* MAC Auto-Neg bitmap*/ -#define GMAC_AN_CTRL_RAN BIT(9) -#define GMAC_AN_CTRL_ANE BIT(12) -#define GMAC_AN_CTRL_ELE BIT(14) -#define GMAC_AN_FD BIT(5) -#define GMAC_AN_HD BIT(6) -#define GMAC_AN_PSE_MASK GENMASK(8, 7) -#define GMAC_AN_PSE_SHIFT 7 - /* MAC PMT bitmap */ enum power_event { pointer_reset = 0x80000000, @@ -250,6 +237,23 @@ enum power_event { #define MTL_DEBUG_RRCSTS_FLUSH 3 #define MTL_DEBUG_RWCSTS BIT(0) +/* SGMII/RGMII status register */ +#define GMAC_PHYIF_CTRLSTATUS_TC BIT(0) +#define GMAC_PHYIF_CTRLSTATUS_LUD BIT(1) +#define GMAC_PHYIF_CTRLSTATUS_SMIDRXS BIT(4) +#define GMAC_PHYIF_CTRLSTATUS_LNKMOD BIT(16) +#define GMAC_PHYIF_CTRLSTATUS_SPEED GENMASK(18, 17) +#define GMAC_PHYIF_CTRLSTATUS_SPEED_SHIFT 17 +#define GMAC_PHYIF_CTRLSTATUS_LNKSTS BIT(19) +#define GMAC_PHYIF_CTRLSTATUS_JABTO BIT(20) +#define GMAC_PHYIF_CTRLSTATUS_FALSECARDET BIT(21) +/* LNKMOD */ +#define GMAC_PHYIF_CTRLSTATUS_LNKMOD_MASK 0x1 +/* LNKSPEED */ +#define GMAC_PHYIF_CTRLSTATUS_SPEED_125 0x2 +#define GMAC_PHYIF_CTRLSTATUS_SPEED_25 0x1 +#define GMAC_PHYIF_CTRLSTATUS_SPEED_2_5 0x0 + extern const struct stmmac_dma_ops dwmac4_dma_ops; extern const struct stmmac_dma_ops dwmac410_dma_ops; #endif /* __DWMAC4_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 44da877d2483..207d8bb0c80b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -17,6 +17,7 @@ #include #include #include +#include "stmmac_pcs.h" #include "dwmac4.h" static void dwmac4_core_init(struct mac_device_info *hw, int mtu) @@ -190,39 +191,53 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, } } -static void dwmac4_ctrl_ane(struct mac_device_info *hw, bool restart) +static void dwmac4_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral, + bool loopback) { - void __iomem *ioaddr = hw->pcsr; - - /* auto negotiation enable and External Loopback enable */ - u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE; + dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback); +} - if (restart) - value |= GMAC_AN_CTRL_RAN; +static void dwmac4_rane(void __iomem *ioaddr, bool restart) +{ + dwmac_rane(ioaddr, GMAC_PCS_BASE, restart); +} - writel(value, ioaddr + GMAC_AN_CTRL); +static void dwmac4_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv) +{ + dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv); } -static void dwmac4_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv) +/* RGMII or SMII interface */ +static void dwmac4_phystatus(void __iomem *ioaddr, struct stmmac_extra_stats *x) { - void __iomem *ioaddr = hw->pcsr; - u32 value = readl(ioaddr + GMAC_AN_ADV); + u32 status; - if (value & GMAC_AN_FD) - adv->duplex = DUPLEX_FULL; - if (value & GMAC_AN_HD) - adv->duplex |= DUPLEX_HALF; + status = readl(ioaddr + GMAC_PHYIF_CONTROL_STATUS); + x->irq_rgmii_n++; - adv->pause = (value & GMAC_AN_PSE_MASK) >> GMAC_AN_PSE_SHIFT; + /* Check the link status */ + if (status & GMAC_PHYIF_CTRLSTATUS_LNKSTS) { + int speed_value; - value = readl(ioaddr + GMAC_AN_LPA); + x->pcs_link = 1; - if (value & GMAC_AN_FD) - adv->lp_duplex = DUPLEX_FULL; - if (value & GMAC_AN_HD) - adv->lp_duplex = DUPLEX_HALF; + speed_value = ((status & GMAC_PHYIF_CTRLSTATUS_SPEED) >> + GMAC_PHYIF_CTRLSTATUS_SPEED_SHIFT); + if (speed_value == GMAC_PHYIF_CTRLSTATUS_SPEED_125) + x->pcs_speed = SPEED_1000; + else if (speed_value == GMAC_PHYIF_CTRLSTATUS_SPEED_25) + x->pcs_speed = SPEED_100; + else + x->pcs_speed = SPEED_10; + + x->pcs_duplex = (status & GMAC_PHYIF_CTRLSTATUS_LNKMOD_MASK); - adv->lp_pause = (value & GMAC_AN_PSE_MASK) >> GMAC_AN_PSE_SHIFT; + pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed, + x->pcs_duplex ? "Full" : "Half"); + } else { + x->pcs_link = 0; + pr_info("Link is Down\n"); + } } static int dwmac4_irq_status(struct mac_device_info *hw, @@ -248,11 +263,6 @@ static int dwmac4_irq_status(struct mac_device_info *hw, x->irq_receive_pmt_irq_n++; } - if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) { - readl(ioaddr + GMAC_AN_STATUS); - x->irq_pcs_ane_n++; - } - mtl_int_qx_status = readl(ioaddr + MTL_INT_STATUS); /* Check MTL Interrupt: Currently only one queue is used: Q0. */ if (mtl_int_qx_status & MTL_INT_Q0) { @@ -267,6 +277,10 @@ static int dwmac4_irq_status(struct mac_device_info *hw, } } + dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); + if (intr_status & PCS_RGSMIIIS_IRQ) + dwmac4_phystatus(ioaddr, x); + return ret; } @@ -363,8 +377,9 @@ static const struct stmmac_ops dwmac4_ops = { .pmt = dwmac4_pmt, .set_umac_addr = dwmac4_set_umac_addr, .get_umac_addr = dwmac4_get_umac_addr, - .ctrl_ane = dwmac4_ctrl_ane, - .get_adv = dwmac4_get_adv, + .pcs_ctrl_ane = dwmac4_ctrl_ane, + .pcs_rane = dwmac4_rane, + .pcs_get_adv_lp = dwmac4_get_adv_lp, .debug = dwmac4_debug, .set_filter = dwmac4_set_filter, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index e2b98b01647e..a5f4f46da42b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -289,10 +289,10 @@ static int stmmac_ethtool_getsettings(struct net_device *dev, ethtool_cmd_speed_set(cmd, priv->xstats.pcs_speed); /* Get and convert ADV/LP_ADV from the HW AN registers */ - if (!priv->hw->mac->get_adv) + if (!priv->hw->mac->pcs_get_adv_lp) return -EOPNOTSUPP; /* should never happen indeed */ - priv->hw->mac->get_adv(priv->hw, &adv); + priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv); /* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */ @@ -376,8 +376,10 @@ static int stmmac_ethtool_setsettings(struct net_device *dev, ADVERTISED_10baseT_Full); spin_lock(&priv->lock); - if (priv->hw->mac->ctrl_ane) - priv->hw->mac->ctrl_ane(priv->hw, 1); + + if (priv->hw->mac->pcs_ctrl_ane) + priv->hw->mac->pcs_ctrl_ane(priv->ioaddr, 1, 0, 0); + spin_unlock(&priv->lock); return 0; @@ -452,11 +454,22 @@ stmmac_get_pauseparam(struct net_device *netdev, { struct stmmac_priv *priv = netdev_priv(netdev); - if (priv->pcs) /* FIXME */ - return; - pause->rx_pause = 0; pause->tx_pause = 0; + + if (priv->pcs && priv->hw->mac->pcs_get_adv_lp) { + struct rgmii_adv adv_lp; + + pause->autoneg = 1; + priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv_lp); + if (!adv_lp.pause) + return; + } else { + if (!(priv->phydev->supported & SUPPORTED_Pause) || + !(priv->phydev->supported & SUPPORTED_Asym_Pause)) + return; + } + pause->autoneg = priv->phydev->autoneg; if (priv->flow_ctrl & FLOW_RX) @@ -473,10 +486,19 @@ stmmac_set_pauseparam(struct net_device *netdev, struct stmmac_priv *priv = netdev_priv(netdev); struct phy_device *phy = priv->phydev; int new_pause = FLOW_OFF; - int ret = 0; - if (priv->pcs) /* FIXME */ - return -EOPNOTSUPP; + if (priv->pcs && priv->hw->mac->pcs_get_adv_lp) { + struct rgmii_adv adv_lp; + + pause->autoneg = 1; + priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv_lp); + if (!adv_lp.pause) + return -EOPNOTSUPP; + } else { + if (!(phy->supported & SUPPORTED_Pause) || + !(phy->supported & SUPPORTED_Asym_Pause)) + return -EOPNOTSUPP; + } if (pause->rx_pause) new_pause |= FLOW_RX; @@ -485,14 +507,14 @@ stmmac_set_pauseparam(struct net_device *netdev, priv->flow_ctrl = new_pause; phy->autoneg = pause->autoneg; - if (phy->autoneg) { if (netif_running(netdev)) - ret = phy_start_aneg(phy); - } else - priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, - priv->flow_ctrl, priv->pause); - return ret; + return phy_start_aneg(phy); + } + + priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, priv->flow_ctrl, + priv->pause); + return 0; } static void stmmac_get_ethtool_stats(struct net_device *dev, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a473c182c91d..6c43d6825172 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1714,8 +1714,8 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); } - if (priv->pcs && priv->hw->mac->ctrl_ane) - priv->hw->mac->ctrl_ane(priv->hw, 0); + if (priv->pcs && priv->hw->mac->pcs_ctrl_ane) + priv->hw->mac->pcs_ctrl_ane(priv->hw, 1, 0, 0); /* set TX ring length */ if (priv->hw->dma->set_tx_ring_len) @@ -2809,6 +2809,14 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) priv->rx_tail_addr, STMMAC_CHAN0); } + + /* PCS link status */ + if (priv->pcs) { + if (priv->xstats.pcs_link) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + } } /* To handle DMA interrupts */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h new file mode 100644 index 000000000000..eba41c24b7a7 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h @@ -0,0 +1,159 @@ +/* + * stmmac_pcs.h: Physical Coding Sublayer Header File + * + * Copyright (C) 2016 STMicroelectronics (R&D) Limited + * Author: Giuseppe Cavallaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __STMMAC_PCS_H__ +#define __STMMAC_PCS_H__ + +#include +#include +#include "common.h" + +/* PCS registers (AN/TBI/SGMII/RGMII) offsets */ +#define GMAC_AN_CTRL(x) (x) /* AN control */ +#define GMAC_AN_STATUS(x) (x + 0x4) /* AN status */ +#define GMAC_ANE_ADV(x) (x + 0x8) /* ANE Advertisement */ +#define GMAC_ANE_LPA(x) (x + 0xc) /* ANE link partener ability */ +#define GMAC_ANE_EXP(x) (x + 0x10) /* ANE expansion */ +#define GMAC_TBI(x) (x + 0x14) /* TBI extend status */ + +/* AN Configuration defines */ +#define GMAC_AN_CTRL_RAN BIT(9) /* Restart Auto-Negotiation */ +#define GMAC_AN_CTRL_ANE BIT(12) /* Auto-Negotiation Enable */ +#define GMAC_AN_CTRL_ELE BIT(14) /* External Loopback Enable */ +#define GMAC_AN_CTRL_ECD BIT(16) /* Enable Comma Detect */ +#define GMAC_AN_CTRL_LR BIT(17) /* Lock to Reference */ +#define GMAC_AN_CTRL_SGMRAL BIT(18) /* SGMII RAL Control */ + +/* AN Status defines */ +#define GMAC_AN_STATUS_LS BIT(2) /* Link Status 0:down 1:up */ +#define GMAC_AN_STATUS_ANA BIT(3) /* Auto-Negotiation Ability */ +#define GMAC_AN_STATUS_ANC BIT(5) /* Auto-Negotiation Complete */ +#define GMAC_AN_STATUS_ES BIT(8) /* Extended Status */ + +/* ADV and LPA defines */ +#define GMAC_ANE_FD BIT(5) +#define GMAC_ANE_HD BIT(6) +#define GMAC_ANE_PSE GENMASK(8, 7) +#define GMAC_ANE_PSE_SHIFT 7 +#define GMAC_ANE_RFE GENMASK(13, 12) +#define GMAC_ANE_RFE_SHIFT 12 +#define GMAC_ANE_ACK BIT(14) + +/** + * dwmac_pcs_isr - TBI, RTBI, or SGMII PHY ISR + * @ioaddr: IO registers pointer + * @reg: Base address of the AN Control Register. + * @intr_status: GMAC core interrupt status + * @x: pointer to log these events as stats + * Description: it is the ISR for PCS events: Auto-Negotiation Completed and + * Link status. + */ +static inline void dwmac_pcs_isr(void __iomem *ioaddr, u32 reg, + unsigned int intr_status, + struct stmmac_extra_stats *x) +{ + u32 val = readl(ioaddr + GMAC_AN_STATUS(reg)); + + if (intr_status & PCS_ANE_IRQ) { + x->irq_pcs_ane_n++; + if (val & GMAC_AN_STATUS_ANC) + pr_info("stmmac_pcs: ANE process completed\n"); + } + + if (intr_status & PCS_LINK_IRQ) { + x->irq_pcs_link_n++; + if (val & GMAC_AN_STATUS_LS) + pr_info("stmmac_pcs: Link Up\n"); + else + pr_info("stmmac_pcs: Link Down\n"); + } +} + +/** + * dwmac_rane - To restart ANE + * @ioaddr: IO registers pointer + * @reg: Base address of the AN Control Register. + * @restart: to restart ANE + * Description: this is to just restart the Auto-Negotiation. + */ +static inline void dwmac_rane(void __iomem *ioaddr, u32 reg, bool restart) +{ + u32 value = readl(ioaddr + GMAC_AN_CTRL(reg)); + + if (restart) + value |= GMAC_AN_CTRL_RAN; + + writel(value, ioaddr + GMAC_AN_CTRL(reg)); +} + +/** + * dwmac_ctrl_ane - To program the AN Control Register. + * @ioaddr: IO registers pointer + * @reg: Base address of the AN Control Register. + * @ane: to enable the auto-negotiation + * @srgmi_ral: to manage MAC-2-MAC SGMII connections. + * @loopback: to cause the PHY to loopback tx data into rx path. + * Description: this is the main function to configure the AN control register + * and init the ANE, select loopback (usually for debugging purpose) and + * configure SGMII RAL. + */ +static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane, + bool srgmi_ral, bool loopback) +{ + u32 value = readl(ioaddr + GMAC_AN_CTRL(reg)); + + /* Enable and restart the Auto-Negotiation */ + if (ane) + value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN; + + /* In case of MAC-2-MAC connection, block is configured to operate + * according to MAC conf register. + */ + if (srgmi_ral) + value |= GMAC_AN_CTRL_SGMRAL; + + if (loopback) + value |= GMAC_AN_CTRL_ELE; + + writel(value, ioaddr + GMAC_AN_CTRL(reg)); +} + +/** + * dwmac_get_adv_lp - Get ADV and LP cap + * @ioaddr: IO registers pointer + * @reg: Base address of the AN Control Register. + * @adv_lp: structure to store the adv,lp status + * Description: this is to expose the ANE advertisement and Link partner ability + * status to ethtool support. + */ +static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg, + struct rgmii_adv *adv_lp) +{ + u32 value = readl(ioaddr + GMAC_ANE_ADV(reg)); + + if (value & GMAC_ANE_FD) + adv_lp->duplex = DUPLEX_FULL; + if (value & GMAC_ANE_HD) + adv_lp->duplex |= DUPLEX_HALF; + + adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; + + value = readl(ioaddr + GMAC_ANE_LPA(reg)); + + if (value & GMAC_ANE_FD) + adv_lp->lp_duplex = DUPLEX_FULL; + if (value & GMAC_ANE_HD) + adv_lp->lp_duplex = DUPLEX_HALF; + + adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; +} +#endif /* __STMMAC_PCS_H__ */ -- cgit v1.3-14-g43fede From 02e57b9d7c8ce9e403f15f48fb91dd6549aaf465 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Fri, 24 Jun 2016 15:16:26 +0200 Subject: drivers: net: stmmac: add port selection programming In case of SGMII more, for example when a MAC2MAC connection is needed, the port selection bits (inside the MAC configuration registers) have to be programmed according to the link selected. So the patch adds a new DT parameter to pass the port selection and to programmed related PCS and CORE to use it. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/stmmac.txt | 3 +++ drivers/net/ethernet/stmicro/stmmac/common.h | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 15 +++++++++++++++ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 15 +++++++++++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 3 ++- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 15 ++++++++++++++- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 2 ++ include/linux/stmmac.h | 1 + 8 files changed, 53 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index 95816c5fc589..41b49e6075f5 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -47,6 +47,9 @@ Optional properties: supported by this device instance - snps,perfect-filter-entries: Number of perfect filter entries supported by this device instance +- snps,ps-speed: port selection speed that can be passed to the core when + PCS is supported. For example, this is used in case of SGMII + and MAC2MAC connection. - AXI BUS Mode parameters: below the list of all the parameters to program the AXI register inside the DMA module: - snps,lpi_en: enable Low Power Interface diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 51077a8dc1f5..2533b91f1421 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -531,6 +531,7 @@ struct mac_device_info { unsigned int rx_csum; unsigned int pcs; unsigned int pmt; + unsigned int ps; }; struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 0d31f2f80d07..cbefe9e2207c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -46,6 +46,21 @@ static void dwmac1000_core_init(struct mac_device_info *hw, int mtu) if (mtu > 2000) value |= GMAC_CONTROL_JE; + if (hw->ps) { + value |= GMAC_CONTROL_TE; + + if (hw->ps == SPEED_1000) { + value &= ~GMAC_CONTROL_PS; + } else { + value |= GMAC_CONTROL_PS; + + if (hw->ps == SPEED_10) + value &= ~GMAC_CONTROL_FES; + else + value |= GMAC_CONTROL_FES; + } + } + writel(value, ioaddr + GMAC_CONTROL); /* Mask GMAC interrupts */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 747f3cf1e20b..df5580dcdfed 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -32,6 +32,21 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu) if (mtu > 2000) value |= GMAC_CONFIG_JE; + if (hw->ps) { + value |= GMAC_CONFIG_TE; + + if (hw->ps == SPEED_1000) { + value &= ~GMAC_CONFIG_PS; + } else { + value |= GMAC_CONFIG_PS; + + if (hw->ps == SPEED_10) + value &= ~GMAC_CONFIG_FES; + else + value |= GMAC_CONFIG_FES; + } + } + writel(value, ioaddr + GMAC_CONFIG); /* Mask GMAC interrupts */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index da2d9b5b740a..1e06173fc9d7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -380,7 +380,8 @@ static int stmmac_ethtool_setsettings(struct net_device *dev, spin_lock(&priv->lock); if (priv->hw->mac->pcs_ctrl_ane) - priv->hw->mac->pcs_ctrl_ane(priv->ioaddr, 1, 0, 0); + priv->hw->mac->pcs_ctrl_ane(priv->ioaddr, 1, + priv->hw->ps, 0); spin_unlock(&priv->lock); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 6142fce9ffac..aab777c1ba33 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1666,6 +1666,19 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) if (priv->plat->bus_setup) priv->plat->bus_setup(priv->ioaddr); + /* PS and related bits will be programmed according to the speed */ + if (priv->hw->pcs) { + int speed = priv->plat->mac_port_sel_speed; + + if ((speed == SPEED_10) || (speed == SPEED_100) || + (speed == SPEED_1000)) { + priv->hw->ps = speed; + } else { + dev_warn(priv->device, "invalid port speed\n"); + priv->hw->ps = 0; + } + } + /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->hw, dev->mtu); @@ -1716,7 +1729,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) } if (priv->hw->pcs && priv->hw->mac->pcs_ctrl_ane) - priv->hw->mac->pcs_ctrl_ane(priv->hw, 1, 0, 0); + priv->hw->mac->pcs_ctrl_ane(priv->hw, 1, priv->hw->ps, 0); /* set TX ring length */ if (priv->hw->dma->set_tx_ring_len) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index a96714d34560..f7dfc0ae8e9c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -319,6 +319,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set."); } + of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed); + plat->axi = stmmac_axi_setup(pdev); return plat; diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 0507dbfbf63c..705840e0438f 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -141,5 +141,6 @@ struct plat_stmmacenet_data { struct stmmac_axi *axi; int has_gmac4; bool tso_en; + int mac_port_sel_speed; }; #endif -- cgit v1.3-14-g43fede From beb1a04619f6bcf0e0452780b4c3eaab995e0b43 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 24 Jun 2016 21:23:52 +0300 Subject: net: davinci_mdio: document missed "ti, am4372-mdio" compat string Document missed "ti,am4372-mdio" compat string used for TI am437x SoC (am4372.dtsi). Signed-off-by: Grygorii Strashko Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/davinci-mdio.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt b/Documentation/devicetree/bindings/net/davinci-mdio.txt index 0369e25aabd2..b6a4f487a823 100644 --- a/Documentation/devicetree/bindings/net/davinci-mdio.txt +++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt @@ -2,7 +2,9 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings --------------------------------------------------- Required properties: -- compatible : Should be "ti,davinci_mdio" or "ti,keystone_mdio" +- compatible : Should be "ti,davinci_mdio" + and "ti,keystone_mdio" for Keystone 2 SoCs + and "ti,am4372-mdio" for am472x SoC - reg : physical base address and size of the davinci mdio registers map - bus_freq : Mdio Bus frequency -- cgit v1.3-14-g43fede From 22899eca586b862d5761f1b4795a3951fc0e502f Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 24 Jun 2016 21:23:53 +0300 Subject: net: davinci_mdio: introduce "ti,cpsw-mdio" compat string Introduce "ti,cpsw-mdio" compatible string for Davinci MDIO, because it's required to distinguish the case when MDIO is part of TI CPSW to enable features supported by TI CPSW (for example, enable PM management). Signed-off-by: Grygorii Strashko Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/davinci-mdio.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt b/Documentation/devicetree/bindings/net/davinci-mdio.txt index b6a4f487a823..621156ca4ffd 100644 --- a/Documentation/devicetree/bindings/net/davinci-mdio.txt +++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt @@ -4,6 +4,7 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings Required properties: - compatible : Should be "ti,davinci_mdio" and "ti,keystone_mdio" for Keystone 2 SoCs + and "ti,cpsw-mdio" for am335x, am472x, am57xx/dra7, dm814x SoCs and "ti,am4372-mdio" for am472x SoC - reg : physical base address and size of the davinci mdio registers map -- cgit v1.3-14-g43fede From 1bcbf6f4b6b050eaf8f1fb1adf5c4779a3623c5b Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Mon, 7 Sep 2015 08:15:27 -0300 Subject: [media] cec: s5p-cec: Add s5p-cec driver Add CEC interface driver present in the Samsung Exynos range of SoCs. The following files were based on work by SangPil Moon: - exynos_hdmi_cec.h - exynos_hdmi_cecctl.c Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/s5p-cec.txt | 31 +++ MAINTAINERS | 7 + drivers/media/platform/Kconfig | 10 + drivers/media/platform/Makefile | 1 + drivers/media/platform/s5p-cec/Makefile | 2 + drivers/media/platform/s5p-cec/exynos_hdmi_cec.h | 38 +++ .../media/platform/s5p-cec/exynos_hdmi_cecctrl.c | 209 +++++++++++++++ drivers/media/platform/s5p-cec/regs-cec.h | 96 +++++++ drivers/media/platform/s5p-cec/s5p_cec.c | 295 +++++++++++++++++++++ drivers/media/platform/s5p-cec/s5p_cec.h | 76 ++++++ 10 files changed, 765 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/s5p-cec.txt create mode 100644 drivers/media/platform/s5p-cec/Makefile create mode 100644 drivers/media/platform/s5p-cec/exynos_hdmi_cec.h create mode 100644 drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c create mode 100644 drivers/media/platform/s5p-cec/regs-cec.h create mode 100644 drivers/media/platform/s5p-cec/s5p_cec.c create mode 100644 drivers/media/platform/s5p-cec/s5p_cec.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/s5p-cec.txt b/Documentation/devicetree/bindings/media/s5p-cec.txt new file mode 100644 index 000000000000..925ab4d72eaa --- /dev/null +++ b/Documentation/devicetree/bindings/media/s5p-cec.txt @@ -0,0 +1,31 @@ +* Samsung HDMI CEC driver + +The HDMI CEC module is present is Samsung SoCs and its purpose is to +handle communication between HDMI connected devices over the CEC bus. + +Required properties: + - compatible : value should be following + "samsung,s5p-cec" + + - reg : Physical base address of the IP registers and length of memory + mapped region. + + - interrupts : HDMI CEC interrupt number to the CPU. + - clocks : from common clock binding: handle to HDMI CEC clock. + - clock-names : from common clock binding: must contain "hdmicec", + corresponding to entry in the clocks property. + - samsung,syscon-phandle - phandle to the PMU system controller + +Example: + +hdmicec: cec@100B0000 { + compatible = "samsung,s5p-cec"; + reg = <0x100B0000 0x200>; + interrupts = <0 114 0>; + clocks = <&clock CLK_HDMI_CEC>; + clock-names = "hdmicec"; + samsung,syscon-phandle = <&pmu_system_controller>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_cec>; + status = "okay"; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 848d37dafd90..7f76a3bf069f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1642,6 +1642,13 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/media/platform/s5p-tv/ +ARM/SAMSUNG S5P SERIES HDMI CEC SUBSYSTEM SUPPORT +M: Kyungmin Park +L: linux-arm-kernel@lists.infradead.org +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/platform/s5p-cec/ + ARM/SAMSUNG S5P SERIES JPEG CODEC SUPPORT M: Andrzej Pietrasiewicz M: Jacek Anaszewski diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 382f3937379e..567717583246 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -108,6 +108,16 @@ config VIDEO_S3C_CAMIF source "drivers/media/platform/soc_camera/Kconfig" source "drivers/media/platform/exynos4-is/Kconfig" source "drivers/media/platform/s5p-tv/Kconfig" + +config VIDEO_SAMSUNG_S5P_CEC + tristate "Samsung S5P CEC driver" + depends on VIDEO_DEV && MEDIA_CEC && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST) + ---help--- + This is a driver for Samsung S5P HDMI CEC interface. It uses the + generic CEC framework interface. + CEC bus is present in the HDMI connector and enables communication + between compatible devices. + source "drivers/media/platform/am437x/Kconfig" source "drivers/media/platform/xilinx/Kconfig" source "drivers/media/platform/rcar-vin/Kconfig" diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 99cf31542f54..9a2fe9513282 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif/ obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/ +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ diff --git a/drivers/media/platform/s5p-cec/Makefile b/drivers/media/platform/s5p-cec/Makefile new file mode 100644 index 000000000000..0e2cf457825a --- /dev/null +++ b/drivers/media/platform/s5p-cec/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec.o +s5p-cec-y += s5p_cec.o exynos_hdmi_cecctrl.o diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h b/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h new file mode 100644 index 000000000000..3e4fc7b05e83 --- /dev/null +++ b/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h @@ -0,0 +1,38 @@ +/* drivers/media/platform/s5p-cec/exynos_hdmi_cec.h + * + * Copyright (c) 2010, 2014 Samsung Electronics + * http://www.samsung.com/ + * + * Header file for interface of Samsung Exynos hdmi cec hardware + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _EXYNOS_HDMI_CEC_H_ +#define _EXYNOS_HDMI_CEC_H_ __FILE__ + +#include +#include +#include "s5p_cec.h" + +void s5p_cec_set_divider(struct s5p_cec_dev *cec); +void s5p_cec_enable_rx(struct s5p_cec_dev *cec); +void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec); +void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec); +void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec); +void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec); +void s5p_cec_reset(struct s5p_cec_dev *cec); +void s5p_cec_tx_reset(struct s5p_cec_dev *cec); +void s5p_cec_rx_reset(struct s5p_cec_dev *cec); +void s5p_cec_threshold(struct s5p_cec_dev *cec); +void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data, + size_t count, u8 retries); +void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr); +u32 s5p_cec_get_status(struct s5p_cec_dev *cec); +void s5p_clr_pending_tx(struct s5p_cec_dev *cec); +void s5p_clr_pending_rx(struct s5p_cec_dev *cec); +void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer); + +#endif /* _EXYNOS_HDMI_CEC_H_ */ diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c new file mode 100644 index 000000000000..ce95e0fcd882 --- /dev/null +++ b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c @@ -0,0 +1,209 @@ +/* drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c + * + * Copyright (c) 2009, 2014 Samsung Electronics + * http://www.samsung.com/ + * + * cec ftn file for Samsung TVOUT driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include "exynos_hdmi_cec.h" +#include "regs-cec.h" + +#define S5P_HDMI_FIN 24000000 +#define CEC_DIV_RATIO 320000 + +#define CEC_MESSAGE_BROADCAST_MASK 0x0F +#define CEC_MESSAGE_BROADCAST 0x0F +#define CEC_FILTER_THRESHOLD 0x15 + +void s5p_cec_set_divider(struct s5p_cec_dev *cec) +{ + u32 div_ratio, div_val; + unsigned int reg; + + div_ratio = S5P_HDMI_FIN / CEC_DIV_RATIO - 1; + + if (regmap_read(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, ®)) { + dev_err(cec->dev, "failed to read phy control\n"); + return; + } + + reg = (reg & ~(0x3FF << 16)) | (div_ratio << 16); + + if (regmap_write(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, reg)) { + dev_err(cec->dev, "failed to write phy control\n"); + return; + } + + div_val = CEC_DIV_RATIO * 0.00005 - 1; + + writeb(0x0, cec->reg + S5P_CEC_DIVISOR_3); + writeb(0x0, cec->reg + S5P_CEC_DIVISOR_2); + writeb(0x0, cec->reg + S5P_CEC_DIVISOR_1); + writeb(div_val, cec->reg + S5P_CEC_DIVISOR_0); +} + +void s5p_cec_enable_rx(struct s5p_cec_dev *cec) +{ + u8 reg; + + reg = readb(cec->reg + S5P_CEC_RX_CTRL); + reg |= S5P_CEC_RX_CTRL_ENABLE; + writeb(reg, cec->reg + S5P_CEC_RX_CTRL); +} + +void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec) +{ + u8 reg; + + reg = readb(cec->reg + S5P_CEC_IRQ_MASK); + reg |= S5P_CEC_IRQ_RX_DONE; + reg |= S5P_CEC_IRQ_RX_ERROR; + writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); +} + +void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec) +{ + u8 reg; + + reg = readb(cec->reg + S5P_CEC_IRQ_MASK); + reg &= ~S5P_CEC_IRQ_RX_DONE; + reg &= ~S5P_CEC_IRQ_RX_ERROR; + writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); +} + +void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec) +{ + u8 reg; + + reg = readb(cec->reg + S5P_CEC_IRQ_MASK); + reg |= S5P_CEC_IRQ_TX_DONE; + reg |= S5P_CEC_IRQ_TX_ERROR; + writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); + +} + +void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec) +{ + u8 reg; + + reg = readb(cec->reg + S5P_CEC_IRQ_MASK); + reg &= ~S5P_CEC_IRQ_TX_DONE; + reg &= ~S5P_CEC_IRQ_TX_ERROR; + writeb(reg, cec->reg + S5P_CEC_IRQ_MASK); +} + +void s5p_cec_reset(struct s5p_cec_dev *cec) +{ + u8 reg; + + writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL); + writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL); + + reg = readb(cec->reg + 0xc4); + reg &= ~0x1; + writeb(reg, cec->reg + 0xc4); +} + +void s5p_cec_tx_reset(struct s5p_cec_dev *cec) +{ + writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL); +} + +void s5p_cec_rx_reset(struct s5p_cec_dev *cec) +{ + u8 reg; + + writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL); + + reg = readb(cec->reg + 0xc4); + reg &= ~0x1; + writeb(reg, cec->reg + 0xc4); +} + +void s5p_cec_threshold(struct s5p_cec_dev *cec) +{ + writeb(CEC_FILTER_THRESHOLD, cec->reg + S5P_CEC_RX_FILTER_TH); + writeb(0, cec->reg + S5P_CEC_RX_FILTER_CTRL); +} + +void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data, + size_t count, u8 retries) +{ + int i = 0; + u8 reg; + + while (i < count) { + writeb(data[i], cec->reg + (S5P_CEC_TX_BUFF0 + (i * 4))); + i++; + } + + writeb(count, cec->reg + S5P_CEC_TX_BYTES); + reg = readb(cec->reg + S5P_CEC_TX_CTRL); + reg |= S5P_CEC_TX_CTRL_START; + reg &= ~0x70; + reg |= retries << 4; + + if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST) { + dev_dbg(cec->dev, "Broadcast"); + reg |= S5P_CEC_TX_CTRL_BCAST; + } else { + dev_dbg(cec->dev, "No Broadcast"); + reg &= ~S5P_CEC_TX_CTRL_BCAST; + } + + writeb(reg, cec->reg + S5P_CEC_TX_CTRL); + dev_dbg(cec->dev, "cec-tx: cec count (%zu): %*ph", count, + (int)count, data); +} + +void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr) +{ + writeb(addr & 0x0F, cec->reg + S5P_CEC_LOGIC_ADDR); +} + +u32 s5p_cec_get_status(struct s5p_cec_dev *cec) +{ + u32 status = 0; + + status = readb(cec->reg + S5P_CEC_STATUS_0); + status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8; + status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16; + status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24; + + dev_dbg(cec->dev, "status = 0x%x!\n", status); + + return status; +} + +void s5p_clr_pending_tx(struct s5p_cec_dev *cec) +{ + writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR, + cec->reg + S5P_CEC_IRQ_CLEAR); +} + +void s5p_clr_pending_rx(struct s5p_cec_dev *cec) +{ + writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR, + cec->reg + S5P_CEC_IRQ_CLEAR); +} + +void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer) +{ + u32 i = 0; + char debug[40]; + + while (i < size) { + buffer[i] = readb(cec->reg + S5P_CEC_RX_BUFF0 + (i * 4)); + sprintf(debug + i * 2, "%02x ", buffer[i]); + i++; + } + dev_dbg(cec->dev, "cec-rx: cec size(%d): %s", size, debug); +} diff --git a/drivers/media/platform/s5p-cec/regs-cec.h b/drivers/media/platform/s5p-cec/regs-cec.h new file mode 100644 index 000000000000..b2e7e129920e --- /dev/null +++ b/drivers/media/platform/s5p-cec/regs-cec.h @@ -0,0 +1,96 @@ +/* drivers/media/platform/s5p-cec/regs-cec.h + * + * Copyright (c) 2010 Samsung Electronics + * http://www.samsung.com/ + * + * register header file for Samsung TVOUT driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __EXYNOS_REGS__H +#define __EXYNOS_REGS__H + +/* + * Register part + */ +#define S5P_CEC_STATUS_0 (0x0000) +#define S5P_CEC_STATUS_1 (0x0004) +#define S5P_CEC_STATUS_2 (0x0008) +#define S5P_CEC_STATUS_3 (0x000C) +#define S5P_CEC_IRQ_MASK (0x0010) +#define S5P_CEC_IRQ_CLEAR (0x0014) +#define S5P_CEC_LOGIC_ADDR (0x0020) +#define S5P_CEC_DIVISOR_0 (0x0030) +#define S5P_CEC_DIVISOR_1 (0x0034) +#define S5P_CEC_DIVISOR_2 (0x0038) +#define S5P_CEC_DIVISOR_3 (0x003C) + +#define S5P_CEC_TX_CTRL (0x0040) +#define S5P_CEC_TX_BYTES (0x0044) +#define S5P_CEC_TX_STAT0 (0x0060) +#define S5P_CEC_TX_STAT1 (0x0064) +#define S5P_CEC_TX_BUFF0 (0x0080) +#define S5P_CEC_TX_BUFF1 (0x0084) +#define S5P_CEC_TX_BUFF2 (0x0088) +#define S5P_CEC_TX_BUFF3 (0x008C) +#define S5P_CEC_TX_BUFF4 (0x0090) +#define S5P_CEC_TX_BUFF5 (0x0094) +#define S5P_CEC_TX_BUFF6 (0x0098) +#define S5P_CEC_TX_BUFF7 (0x009C) +#define S5P_CEC_TX_BUFF8 (0x00A0) +#define S5P_CEC_TX_BUFF9 (0x00A4) +#define S5P_CEC_TX_BUFF10 (0x00A8) +#define S5P_CEC_TX_BUFF11 (0x00AC) +#define S5P_CEC_TX_BUFF12 (0x00B0) +#define S5P_CEC_TX_BUFF13 (0x00B4) +#define S5P_CEC_TX_BUFF14 (0x00B8) +#define S5P_CEC_TX_BUFF15 (0x00BC) + +#define S5P_CEC_RX_CTRL (0x00C0) +#define S5P_CEC_RX_STAT0 (0x00E0) +#define S5P_CEC_RX_STAT1 (0x00E4) +#define S5P_CEC_RX_BUFF0 (0x0100) +#define S5P_CEC_RX_BUFF1 (0x0104) +#define S5P_CEC_RX_BUFF2 (0x0108) +#define S5P_CEC_RX_BUFF3 (0x010C) +#define S5P_CEC_RX_BUFF4 (0x0110) +#define S5P_CEC_RX_BUFF5 (0x0114) +#define S5P_CEC_RX_BUFF6 (0x0118) +#define S5P_CEC_RX_BUFF7 (0x011C) +#define S5P_CEC_RX_BUFF8 (0x0120) +#define S5P_CEC_RX_BUFF9 (0x0124) +#define S5P_CEC_RX_BUFF10 (0x0128) +#define S5P_CEC_RX_BUFF11 (0x012C) +#define S5P_CEC_RX_BUFF12 (0x0130) +#define S5P_CEC_RX_BUFF13 (0x0134) +#define S5P_CEC_RX_BUFF14 (0x0138) +#define S5P_CEC_RX_BUFF15 (0x013C) + +#define S5P_CEC_RX_FILTER_CTRL (0x0180) +#define S5P_CEC_RX_FILTER_TH (0x0184) + +/* + * Bit definition part + */ +#define S5P_CEC_IRQ_TX_DONE (1<<0) +#define S5P_CEC_IRQ_TX_ERROR (1<<1) +#define S5P_CEC_IRQ_RX_DONE (1<<4) +#define S5P_CEC_IRQ_RX_ERROR (1<<5) + +#define S5P_CEC_TX_CTRL_START (1<<0) +#define S5P_CEC_TX_CTRL_BCAST (1<<1) +#define S5P_CEC_TX_CTRL_RETRY (0x04<<4) +#define S5P_CEC_TX_CTRL_RESET (1<<7) + +#define S5P_CEC_RX_CTRL_ENABLE (1<<0) +#define S5P_CEC_RX_CTRL_RESET (1<<7) + +#define S5P_CEC_LOGIC_ADDR_MASK (0xF) + +/* PMU Registers for PHY */ +#define EXYNOS_HDMI_PHY_CONTROL 0x700 + +#endif /* __EXYNOS_REGS__H */ diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c new file mode 100644 index 000000000000..3844f3915220 --- /dev/null +++ b/drivers/media/platform/s5p-cec/s5p_cec.c @@ -0,0 +1,295 @@ +/* drivers/media/platform/s5p-cec/s5p_cec.c + * + * Samsung S5P CEC driver + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This driver is based on the "cec interface driver for exynos soc" by + * SangPil Moon. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exynos_hdmi_cec.h" +#include "regs-cec.h" +#include "s5p_cec.h" + +#define CEC_NAME "s5p-cec" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "debug level (0-2)"); + +static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct s5p_cec_dev *cec = adap->priv; + int ret; + + if (enable) { + ret = pm_runtime_get_sync(cec->dev); + + s5p_cec_reset(cec); + + s5p_cec_set_divider(cec); + s5p_cec_threshold(cec); + + s5p_cec_unmask_tx_interrupts(cec); + s5p_cec_unmask_rx_interrupts(cec); + s5p_cec_enable_rx(cec); + } else { + s5p_cec_mask_tx_interrupts(cec); + s5p_cec_mask_rx_interrupts(cec); + pm_runtime_disable(cec->dev); + } + + return 0; +} + +static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) +{ + struct s5p_cec_dev *cec = adap->priv; + + s5p_cec_set_addr(cec, addr); + return 0; +} + +static int s5p_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct s5p_cec_dev *cec = adap->priv; + + /* + * Unclear if 0 retries are allowed by the hardware, so have 1 as + * the minimum. + */ + s5p_cec_copy_packet(cec, msg->msg, msg->len, max(1, attempts - 1)); + return 0; +} + +static irqreturn_t s5p_cec_irq_handler(int irq, void *priv) +{ + struct s5p_cec_dev *cec = priv; + u32 status = 0; + + status = s5p_cec_get_status(cec); + + dev_dbg(cec->dev, "irq received\n"); + + if (status & CEC_STATUS_TX_DONE) { + if (status & CEC_STATUS_TX_ERROR) { + dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n"); + cec->tx = STATE_ERROR; + } else { + dev_dbg(cec->dev, "CEC_STATUS_TX_DONE\n"); + cec->tx = STATE_DONE; + } + s5p_clr_pending_tx(cec); + } + + if (status & CEC_STATUS_RX_DONE) { + if (status & CEC_STATUS_RX_ERROR) { + dev_dbg(cec->dev, "CEC_STATUS_RX_ERROR set\n"); + s5p_cec_rx_reset(cec); + s5p_cec_enable_rx(cec); + } else { + dev_dbg(cec->dev, "CEC_STATUS_RX_DONE set\n"); + if (cec->rx != STATE_IDLE) + dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n"); + cec->rx = STATE_BUSY; + cec->msg.len = status >> 24; + cec->msg.rx_status = CEC_RX_STATUS_OK; + s5p_cec_get_rx_buf(cec, cec->msg.len, + cec->msg.msg); + cec->rx = STATE_DONE; + s5p_cec_enable_rx(cec); + } + /* Clear interrupt pending bit */ + s5p_clr_pending_rx(cec); + } + return IRQ_WAKE_THREAD; +} + +static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv) +{ + struct s5p_cec_dev *cec = priv; + + dev_dbg(cec->dev, "irq processing thread\n"); + switch (cec->tx) { + case STATE_DONE: + cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); + cec->tx = STATE_IDLE; + break; + case STATE_ERROR: + cec_transmit_done(cec->adap, + CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR, + 0, 0, 0, 1); + cec->tx = STATE_IDLE; + break; + case STATE_BUSY: + dev_err(cec->dev, "state set to busy, this should not occur here\n"); + break; + default: + break; + } + + switch (cec->rx) { + case STATE_DONE: + cec_received_msg(cec->adap, &cec->msg); + cec->rx = STATE_IDLE; + break; + default: + break; + } + + return IRQ_HANDLED; +} + +static const struct cec_adap_ops s5p_cec_adap_ops = { + .adap_enable = s5p_cec_adap_enable, + .adap_log_addr = s5p_cec_adap_log_addr, + .adap_transmit = s5p_cec_adap_transmit, +}; + +static int s5p_cec_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + struct s5p_cec_dev *cec; + int ret; + + cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + cec->dev = dev; + + cec->irq = platform_get_irq(pdev, 0); + if (cec->irq < 0) + return cec->irq; + + ret = devm_request_threaded_irq(dev, cec->irq, s5p_cec_irq_handler, + s5p_cec_irq_handler_thread, 0, pdev->name, cec); + if (ret) + return ret; + + cec->clk = devm_clk_get(dev, "hdmicec"); + if (IS_ERR(cec->clk)) + return PTR_ERR(cec->clk); + + cec->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,syscon-phandle"); + if (IS_ERR(cec->pmu)) + return -EPROBE_DEFER; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + cec->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(cec->reg)) + return PTR_ERR(cec->reg); + + cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, + CEC_NAME, + CEC_CAP_PHYS_ADDR | CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | + CEC_CAP_PASSTHROUGH | CEC_CAP_RC, + 1, &pdev->dev); + ret = PTR_ERR_OR_ZERO(cec->adap); + if (ret) + return ret; + ret = cec_register_adapter(cec->adap); + if (ret) { + cec_delete_adapter(cec->adap); + return ret; + } + + platform_set_drvdata(pdev, cec); + pm_runtime_enable(dev); + + dev_dbg(dev, "successfuly probed\n"); + return 0; +} + +static int s5p_cec_remove(struct platform_device *pdev) +{ + struct s5p_cec_dev *cec = platform_get_drvdata(pdev); + + cec_unregister_adapter(cec->adap); + pm_runtime_disable(&pdev->dev); + return 0; +} + +static int s5p_cec_runtime_suspend(struct device *dev) +{ + struct s5p_cec_dev *cec = dev_get_drvdata(dev); + + clk_disable_unprepare(cec->clk); + return 0; +} + +static int s5p_cec_runtime_resume(struct device *dev) +{ + struct s5p_cec_dev *cec = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(cec->clk); + if (ret < 0) + return ret; + return 0; +} + +static int s5p_cec_suspend(struct device *dev) +{ + if (pm_runtime_suspended(dev)) + return 0; + return s5p_cec_runtime_suspend(dev); +} + +static int s5p_cec_resume(struct device *dev) +{ + if (pm_runtime_suspended(dev)) + return 0; + return s5p_cec_runtime_resume(dev); +} + +static const struct dev_pm_ops s5p_cec_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(s5p_cec_suspend, s5p_cec_resume) + SET_RUNTIME_PM_OPS(s5p_cec_runtime_suspend, s5p_cec_runtime_resume, + NULL) +}; + +static const struct of_device_id s5p_cec_match[] = { + { + .compatible = "samsung,s5p-cec", + }, + {}, +}; + +static struct platform_driver s5p_cec_pdrv = { + .probe = s5p_cec_probe, + .remove = s5p_cec_remove, + .driver = { + .name = CEC_NAME, + .of_match_table = s5p_cec_match, + .pm = &s5p_cec_pm_ops, + }, +}; + +module_platform_driver(s5p_cec_pdrv); + +MODULE_AUTHOR("Kamil Debski "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Samsung S5P CEC driver"); diff --git a/drivers/media/platform/s5p-cec/s5p_cec.h b/drivers/media/platform/s5p-cec/s5p_cec.h new file mode 100644 index 000000000000..03732c13d19f --- /dev/null +++ b/drivers/media/platform/s5p-cec/s5p_cec.h @@ -0,0 +1,76 @@ +/* drivers/media/platform/s5p-cec/s5p_cec.h + * + * Samsung S5P HDMI CEC driver + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _S5P_CEC_H_ +#define _S5P_CEC_H_ __FILE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exynos_hdmi_cec.h" +#include "regs-cec.h" +#include "s5p_cec.h" + +#define CEC_NAME "s5p-cec" + +#define CEC_STATUS_TX_RUNNING (1 << 0) +#define CEC_STATUS_TX_TRANSFERRING (1 << 1) +#define CEC_STATUS_TX_DONE (1 << 2) +#define CEC_STATUS_TX_ERROR (1 << 3) +#define CEC_STATUS_TX_BYTES (0xFF << 8) +#define CEC_STATUS_RX_RUNNING (1 << 16) +#define CEC_STATUS_RX_RECEIVING (1 << 17) +#define CEC_STATUS_RX_DONE (1 << 18) +#define CEC_STATUS_RX_ERROR (1 << 19) +#define CEC_STATUS_RX_BCAST (1 << 20) +#define CEC_STATUS_RX_BYTES (0xFF << 24) + +#define CEC_WORKER_TX_DONE (1 << 0) +#define CEC_WORKER_RX_MSG (1 << 1) + +/* CEC Rx buffer size */ +#define CEC_RX_BUFF_SIZE 16 +/* CEC Tx buffer size */ +#define CEC_TX_BUFF_SIZE 16 + +enum cec_state { + STATE_IDLE, + STATE_BUSY, + STATE_DONE, + STATE_ERROR +}; + +struct s5p_cec_dev { + struct cec_adapter *adap; + struct clk *clk; + struct device *dev; + struct mutex lock; + struct regmap *pmu; + int irq; + void __iomem *reg; + + enum cec_state rx; + enum cec_state tx; + struct cec_msg msg; +}; + +#endif /* _S5P_CEC_H_ */ -- cgit v1.3-14-g43fede From 6f8adea2b64f7e1215a99935ea079284488736d5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Feb 2016 12:44:21 -0200 Subject: [media] vivid: add CEC emulation The vivid driver has been extended to provide CEC adapters for the HDMI input and HDMI outputs in order to test CEC applications. This CEC emulation is faithful to the CEC timings (i.e., it all at a snail's pace). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/vivid.txt | 36 +++- drivers/media/platform/vivid/Kconfig | 8 + drivers/media/platform/vivid/Makefile | 4 + drivers/media/platform/vivid/vivid-cec.c | 255 +++++++++++++++++++++++ drivers/media/platform/vivid/vivid-cec.h | 33 +++ drivers/media/platform/vivid/vivid-core.c | 118 ++++++++++- drivers/media/platform/vivid/vivid-core.h | 27 +++ drivers/media/platform/vivid/vivid-kthread-cap.c | 13 ++ drivers/media/platform/vivid/vivid-vid-cap.c | 23 +- drivers/media/platform/vivid/vivid-vid-common.c | 7 + 10 files changed, 509 insertions(+), 15 deletions(-) create mode 100644 drivers/media/platform/vivid/vivid-cec.c create mode 100644 drivers/media/platform/vivid/vivid-cec.h (limited to 'Documentation') diff --git a/Documentation/video4linux/vivid.txt b/Documentation/video4linux/vivid.txt index 8da5d2a576bc..1b26519c6ddc 100644 --- a/Documentation/video4linux/vivid.txt +++ b/Documentation/video4linux/vivid.txt @@ -74,7 +74,8 @@ Section 11: Cropping, Composing, Scaling Section 12: Formats Section 13: Capture Overlay Section 14: Output Overlay -Section 15: Some Future Improvements +Section 15: CEC (Consumer Electronics Control) +Section 16: Some Future Improvements Section 1: Configuring the driver @@ -364,7 +365,11 @@ For HDMI inputs it is possible to set the EDID. By default a simple EDID is provided. You can only set the EDID for HDMI inputs. Internally, however, the EDID is shared between all HDMI inputs. -No interpretation is done of the EDID data. +No interpretation is done of the EDID data with the exception of the +physical address. See the CEC section for more details. + +There is a maximum of 15 HDMI inputs (if there are more, then they will be +reduced to 15) since that's the limitation of the EDID physical address. Section 3: Video Output @@ -409,6 +414,9 @@ standard, and for all others a 1:1 pixel aspect ratio is returned. An HDMI output has a valid EDID which can be obtained through VIDIOC_G_EDID. +There is a maximum of 15 HDMI outputs (if there are more, then they will be +reduced to 15) since that's the limitation of the EDID physical address. See +also the CEC section for more details. Section 4: VBI Capture ---------------------- @@ -1108,7 +1116,26 @@ capabilities will slow down the video loop considerably as a lot of checks have to be done per pixel. -Section 15: Some Future Improvements +Section 15: CEC (Consumer Electronics Control) +---------------------------------------------- + +If there are HDMI inputs then a CEC adapter will be created that has +the same number of input ports. This is the equivalent of e.g. a TV that +has that number of inputs. Each HDMI output will also create a +CEC adapter that is hooked up to the corresponding input port, or (if there +are more outputs than inputs) is not hooked up at all. In other words, +this is the equivalent of hooking up each output device to an input port of +the TV. Any remaining output devices remain unconnected. + +The EDID that each output reads reports a unique CEC physical address that is +based on the physical address of the EDID of the input. So if the EDID of the +receiver has physical address A.B.0.0, then each output will see an EDID +containing physical address A.B.C.0 where C is 1 to the number of inputs. If +there are more outputs than inputs then the remaining outputs have a CEC adapter +that is disabled and reports an invalid physical address. + + +Section 16: Some Future Improvements ------------------------------------ Just as a reminder and in no particular order: @@ -1121,8 +1148,6 @@ Just as a reminder and in no particular order: - Fix sequence/field numbering when looping of video with alternate fields - Add support for V4L2_CID_BG_COLOR for video outputs - Add ARGB888 overlay support: better testing of the alpha channel -- Add custom DV timings support -- Add support for V4L2_DV_FL_REDUCED_FPS - Improve pixel aspect support in the tpg code by passing a real v4l2_fract - Use per-queue locks and/or per-device locks to improve throughput - Add support to loop from a specific output to a specific input across @@ -1133,3 +1158,4 @@ Just as a reminder and in no particular order: - Make a thread for the RDS generation, that would help in particular for the "Controls" RDS Rx I/O Mode as the read-only RDS controls could be updated in real-time. +- Changing the EDID should cause hotplug detect emulation to happen. diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig index f535f576913d..8e6918c5c87c 100644 --- a/drivers/media/platform/vivid/Kconfig +++ b/drivers/media/platform/vivid/Kconfig @@ -6,6 +6,7 @@ config VIDEO_VIVID select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select MEDIA_CEC_EDID select VIDEOBUF2_VMALLOC select VIDEO_V4L2_TPG default n @@ -22,6 +23,13 @@ config VIDEO_VIVID Say Y here if you want to test video apps or debug V4L devices. When in doubt, say N. +config VIDEO_VIVID_CEC + bool "Enable CEC emulation support" + depends on VIDEO_VIVID && MEDIA_CEC + ---help--- + When selected the vivid module will emulate the optional + HDMI CEC feature. + config VIDEO_VIVID_MAX_DEVS int "Maximum number of devices" depends on VIDEO_VIVID diff --git a/drivers/media/platform/vivid/Makefile b/drivers/media/platform/vivid/Makefile index 633c8a1b2c27..29738810e3ee 100644 --- a/drivers/media/platform/vivid/Makefile +++ b/drivers/media/platform/vivid/Makefile @@ -3,4 +3,8 @@ vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \ vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \ vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \ vivid-osd.o +ifeq ($(CONFIG_VIDEO_VIVID_CEC),y) + vivid-objs += vivid-cec.o +endif + obj-$(CONFIG_VIDEO_VIVID) += vivid.o diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c new file mode 100644 index 000000000000..b5714fae905d --- /dev/null +++ b/drivers/media/platform/vivid/vivid-cec.c @@ -0,0 +1,255 @@ +/* + * vivid-cec.c - A Virtual Video Test Driver, cec emulation + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "vivid-core.h" +#include "vivid-cec.h" + +void vivid_cec_bus_free_work(struct vivid_dev *dev) +{ + spin_lock(&dev->cec_slock); + while (!list_empty(&dev->cec_work_list)) { + struct vivid_cec_work *cw = + list_first_entry(&dev->cec_work_list, + struct vivid_cec_work, list); + + spin_unlock(&dev->cec_slock); + cancel_delayed_work_sync(&cw->work); + spin_lock(&dev->cec_slock); + list_del(&cw->list); + cec_transmit_done(cw->adap, CEC_TX_STATUS_LOW_DRIVE, 0, 0, 1, 0); + kfree(cw); + } + spin_unlock(&dev->cec_slock); +} + +static struct cec_adapter *vivid_cec_find_dest_adap(struct vivid_dev *dev, + struct cec_adapter *adap, + u8 dest) +{ + unsigned int i; + + if (dest >= 0xf) + return NULL; + + if (adap != dev->cec_rx_adap && dev->cec_rx_adap && + dev->cec_rx_adap->is_configured && + cec_has_log_addr(dev->cec_rx_adap, dest)) + return dev->cec_rx_adap; + + for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) { + if (adap == dev->cec_tx_adap[i]) + continue; + if (!dev->cec_tx_adap[i]->is_configured) + continue; + if (cec_has_log_addr(dev->cec_tx_adap[i], dest)) + return dev->cec_tx_adap[i]; + } + return NULL; +} + +static void vivid_cec_xfer_done_worker(struct work_struct *work) +{ + struct vivid_cec_work *cw = + container_of(work, struct vivid_cec_work, work.work); + struct vivid_dev *dev = cw->dev; + struct cec_adapter *adap = cw->adap; + bool is_poll = cw->msg.len == 1; + u8 dest = cec_msg_destination(&cw->msg); + struct cec_adapter *dest_adap = NULL; + bool valid_dest; + unsigned int i; + + valid_dest = cec_msg_is_broadcast(&cw->msg); + if (!valid_dest) { + dest_adap = vivid_cec_find_dest_adap(dev, adap, dest); + if (dest_adap) + valid_dest = true; + } + cw->tx_status = valid_dest ? CEC_TX_STATUS_OK : CEC_TX_STATUS_NACK; + spin_lock(&dev->cec_slock); + dev->cec_xfer_time_jiffies = 0; + dev->cec_xfer_start_jiffies = 0; + list_del(&cw->list); + spin_unlock(&dev->cec_slock); + cec_transmit_done(cw->adap, cw->tx_status, 0, valid_dest ? 0 : 1, 0, 0); + + if (!is_poll && dest_adap) { + /* Directed message */ + cec_received_msg(dest_adap, &cw->msg); + } else if (!is_poll && valid_dest) { + /* Broadcast message */ + if (adap != dev->cec_rx_adap && + dev->cec_rx_adap->log_addrs.log_addr_mask) + cec_received_msg(dev->cec_rx_adap, &cw->msg); + for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) { + if (adap == dev->cec_tx_adap[i] || + !dev->cec_tx_adap[i]->log_addrs.log_addr_mask) + continue; + cec_received_msg(dev->cec_tx_adap[i], &cw->msg); + } + } + kfree(cw); +} + +static void vivid_cec_xfer_try_worker(struct work_struct *work) +{ + struct vivid_cec_work *cw = + container_of(work, struct vivid_cec_work, work.work); + struct vivid_dev *dev = cw->dev; + + spin_lock(&dev->cec_slock); + if (dev->cec_xfer_time_jiffies) { + list_del(&cw->list); + spin_unlock(&dev->cec_slock); + cec_transmit_done(cw->adap, CEC_TX_STATUS_ARB_LOST, 1, 0, 0, 0); + kfree(cw); + } else { + INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker); + dev->cec_xfer_start_jiffies = jiffies; + dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs); + spin_unlock(&dev->cec_slock); + schedule_delayed_work(&cw->work, dev->cec_xfer_time_jiffies); + } +} + +static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + return 0; +} + +static int vivid_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +{ + return 0; +} + +/* + * One data bit takes 2400 us, each byte needs 10 bits so that's 24000 us + * per byte. + */ +#define USECS_PER_BYTE 24000 + +static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct vivid_dev *dev = adap->priv; + struct vivid_cec_work *cw = kzalloc(sizeof(*cw), GFP_KERNEL); + long delta_jiffies = 0; + + if (cw == NULL) + return -ENOMEM; + cw->dev = dev; + cw->adap = adap; + cw->usecs = CEC_FREE_TIME_TO_USEC(signal_free_time) + + msg->len * USECS_PER_BYTE; + cw->msg = *msg; + + spin_lock(&dev->cec_slock); + list_add(&cw->list, &dev->cec_work_list); + if (dev->cec_xfer_time_jiffies == 0) { + INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker); + dev->cec_xfer_start_jiffies = jiffies; + dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs); + delta_jiffies = dev->cec_xfer_time_jiffies; + } else { + INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_try_worker); + delta_jiffies = dev->cec_xfer_start_jiffies + + dev->cec_xfer_time_jiffies - jiffies; + } + spin_unlock(&dev->cec_slock); + schedule_delayed_work(&cw->work, delta_jiffies < 0 ? 0 : delta_jiffies); + return 0; +} + +static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) +{ + struct vivid_dev *dev = adap->priv; + struct cec_msg reply; + u8 dest = cec_msg_destination(msg); + u16 pa; + u8 disp_ctl; + char osd[14]; + + if (cec_msg_is_broadcast(msg)) + dest = adap->log_addrs.log_addr[0]; + cec_msg_init(&reply, dest, cec_msg_initiator(msg)); + + switch (cec_msg_opcode(msg)) { + case CEC_MSG_SET_STREAM_PATH: + if (cec_is_sink(adap)) + return -ENOMSG; + cec_ops_set_stream_path(msg, &pa); + if (pa != adap->phys_addr) + return -ENOMSG; + cec_msg_active_source(&reply, adap->phys_addr); + cec_transmit_msg(adap, &reply, false); + break; + case CEC_MSG_SET_OSD_STRING: + if (!cec_is_sink(adap)) + return -ENOMSG; + cec_ops_set_osd_string(msg, &disp_ctl, osd); + switch (disp_ctl) { + case CEC_OP_DISP_CTL_DEFAULT: + strcpy(dev->osd, osd); + dev->osd_jiffies = jiffies; + break; + case CEC_OP_DISP_CTL_UNTIL_CLEARED: + strcpy(dev->osd, osd); + dev->osd_jiffies = 0; + break; + case CEC_OP_DISP_CTL_CLEAR: + dev->osd[0] = 0; + dev->osd_jiffies = 0; + break; + default: + cec_msg_feature_abort(&reply, cec_msg_opcode(msg), + CEC_OP_ABORT_INVALID_OP); + cec_transmit_msg(adap, &reply, false); + break; + } + break; + default: + return -ENOMSG; + } + return 0; +} + +static const struct cec_adap_ops vivid_cec_adap_ops = { + .adap_enable = vivid_cec_adap_enable, + .adap_log_addr = vivid_cec_adap_log_addr, + .adap_transmit = vivid_cec_adap_transmit, + .received = vivid_received, +}; + +struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, + unsigned int idx, + struct device *parent, + bool is_source) +{ + char name[sizeof(dev->vid_out_dev.name) + 2]; + u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | + CEC_CAP_PASSTHROUGH | CEC_CAP_RC; + + snprintf(name, sizeof(name), "%s%d", + is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, + idx); + return cec_allocate_adapter(&vivid_cec_adap_ops, dev, + name, caps, 1, parent); +} diff --git a/drivers/media/platform/vivid/vivid-cec.h b/drivers/media/platform/vivid/vivid-cec.h new file mode 100644 index 000000000000..97892afa6b3b --- /dev/null +++ b/drivers/media/platform/vivid/vivid-cec.h @@ -0,0 +1,33 @@ +/* + * vivid-cec.h - A Virtual Video Test Driver, cec emulation + * + * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifdef CONFIG_VIDEO_VIVID_CEC +struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, + unsigned int idx, + struct device *parent, + bool is_source); +void vivid_cec_bus_free_work(struct vivid_dev *dev); + +#else + +static inline void vivid_cec_bus_free_work(struct vivid_dev *dev) +{ +} + +#endif diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index c14da84af09b..9966828bb578 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -46,6 +46,7 @@ #include "vivid-vbi-cap.h" #include "vivid-vbi-out.h" #include "vivid-osd.h" +#include "vivid-cec.h" #include "vivid-ctrls.h" #define VIVID_MODULE_NAME "vivid" @@ -684,6 +685,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) dev->input_name_counter[i] = in_type_counter[dev->input_type[i]]++; } dev->has_audio_inputs = in_type_counter[TV] && in_type_counter[SVID]; + if (in_type_counter[HDMI] == 16) { + /* The CEC physical address only allows for max 15 inputs */ + in_type_counter[HDMI]--; + dev->num_inputs--; + } /* how many outputs do we have and of what type? */ dev->num_outputs = num_outputs[inst]; @@ -696,6 +702,15 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) dev->output_name_counter[i] = out_type_counter[dev->output_type[i]]++; } dev->has_audio_outputs = out_type_counter[SVID]; + if (out_type_counter[HDMI] == 16) { + /* + * The CEC physical address only allows for max 15 inputs, + * so outputs are also limited to 15 to allow for easy + * CEC output to input mapping. + */ + out_type_counter[HDMI]--; + dev->num_outputs--; + } /* do we create a video capture device? */ dev->has_vid_cap = node_type & 0x0001; @@ -1010,6 +1025,17 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) INIT_LIST_HEAD(&dev->vbi_out_active); INIT_LIST_HEAD(&dev->sdr_cap_active); + INIT_LIST_HEAD(&dev->cec_work_list); + spin_lock_init(&dev->cec_slock); + /* + * Same as create_singlethread_workqueue, but now I can use the + * string formatting of alloc_ordered_workqueue. + */ + dev->cec_workqueue = + alloc_ordered_workqueue("vivid-%03d-cec", WQ_MEM_RECLAIM, inst); + if (!dev->cec_workqueue) + goto unreg_dev; + /* start creating the vb2 queues */ if (dev->has_vid_cap) { /* initialize vid_cap queue */ @@ -1117,7 +1143,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) /* finally start creating the device nodes */ if (dev->has_vid_cap) { vfd = &dev->vid_cap_dev; - strlcpy(vfd->name, "vivid-vid-cap", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-vid-cap", inst); vfd->fops = &vivid_fops; vfd->ioctl_ops = &vivid_ioctl_ops; vfd->device_caps = dev->vid_cap_caps; @@ -1133,6 +1160,27 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) vfd->lock = &dev->mutex; video_set_drvdata(vfd, dev); +#ifdef CONFIG_VIDEO_VIVID_CEC + if (in_type_counter[HDMI]) { + struct cec_adapter *adap; + + adap = vivid_cec_alloc_adap(dev, 0, &pdev->dev, false); + ret = PTR_ERR_OR_ZERO(adap); + if (ret < 0) + goto unreg_dev; + dev->cec_rx_adap = adap; + ret = cec_register_adapter(adap); + if (ret < 0) { + cec_delete_adapter(adap); + dev->cec_rx_adap = NULL; + goto unreg_dev; + } + cec_s_phys_addr(adap, 0, false); + v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input %d\n", + dev_name(&adap->devnode.dev), i); + } +#endif + ret = video_register_device(vfd, VFL_TYPE_GRABBER, vid_cap_nr[inst]); if (ret < 0) goto unreg_dev; @@ -1141,8 +1189,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) } if (dev->has_vid_out) { +#ifdef CONFIG_VIDEO_VIVID_CEC + unsigned int bus_cnt = 0; +#endif + vfd = &dev->vid_out_dev; - strlcpy(vfd->name, "vivid-vid-out", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-vid-out", inst); vfd->vfl_dir = VFL_DIR_TX; vfd->fops = &vivid_fops; vfd->ioctl_ops = &vivid_ioctl_ops; @@ -1159,6 +1212,35 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) vfd->lock = &dev->mutex; video_set_drvdata(vfd, dev); +#ifdef CONFIG_VIDEO_VIVID_CEC + for (i = 0; i < dev->num_outputs; i++) { + struct cec_adapter *adap; + + if (dev->output_type[i] != HDMI) + continue; + dev->cec_output2bus_map[i] = bus_cnt; + adap = vivid_cec_alloc_adap(dev, bus_cnt, + &pdev->dev, true); + ret = PTR_ERR_OR_ZERO(adap); + if (ret < 0) + goto unreg_dev; + dev->cec_tx_adap[bus_cnt] = adap; + ret = cec_register_adapter(adap); + if (ret < 0) { + cec_delete_adapter(adap); + dev->cec_tx_adap[bus_cnt] = NULL; + goto unreg_dev; + } + bus_cnt++; + if (bus_cnt <= in_type_counter[HDMI]) + cec_s_phys_addr(adap, bus_cnt << 12, false); + else + cec_s_phys_addr(adap, 0x1000, false); + v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n", + dev_name(&adap->devnode.dev), i); + } +#endif + ret = video_register_device(vfd, VFL_TYPE_GRABBER, vid_out_nr[inst]); if (ret < 0) goto unreg_dev; @@ -1168,7 +1250,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (dev->has_vbi_cap) { vfd = &dev->vbi_cap_dev; - strlcpy(vfd->name, "vivid-vbi-cap", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-vbi-cap", inst); vfd->fops = &vivid_fops; vfd->ioctl_ops = &vivid_ioctl_ops; vfd->device_caps = dev->vbi_cap_caps; @@ -1191,7 +1274,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (dev->has_vbi_out) { vfd = &dev->vbi_out_dev; - strlcpy(vfd->name, "vivid-vbi-out", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-vbi-out", inst); vfd->vfl_dir = VFL_DIR_TX; vfd->fops = &vivid_fops; vfd->ioctl_ops = &vivid_ioctl_ops; @@ -1215,7 +1299,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (dev->has_sdr_cap) { vfd = &dev->sdr_cap_dev; - strlcpy(vfd->name, "vivid-sdr-cap", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-sdr-cap", inst); vfd->fops = &vivid_fops; vfd->ioctl_ops = &vivid_ioctl_ops; vfd->device_caps = dev->sdr_cap_caps; @@ -1234,7 +1319,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (dev->has_radio_rx) { vfd = &dev->radio_rx_dev; - strlcpy(vfd->name, "vivid-rad-rx", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-rad-rx", inst); vfd->fops = &vivid_radio_fops; vfd->ioctl_ops = &vivid_ioctl_ops; vfd->device_caps = dev->radio_rx_caps; @@ -1252,7 +1338,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (dev->has_radio_tx) { vfd = &dev->radio_tx_dev; - strlcpy(vfd->name, "vivid-rad-tx", sizeof(vfd->name)); + snprintf(vfd->name, sizeof(vfd->name), + "vivid-%03d-rad-tx", inst); vfd->vfl_dir = VFL_DIR_TX; vfd->fops = &vivid_radio_fops; vfd->ioctl_ops = &vivid_ioctl_ops; @@ -1282,6 +1369,13 @@ unreg_dev: video_unregister_device(&dev->vbi_cap_dev); video_unregister_device(&dev->vid_out_dev); video_unregister_device(&dev->vid_cap_dev); + cec_unregister_adapter(dev->cec_rx_adap); + for (i = 0; i < MAX_OUTPUTS; i++) + cec_unregister_adapter(dev->cec_tx_adap[i]); + if (dev->cec_workqueue) { + vivid_cec_bus_free_work(dev); + destroy_workqueue(dev->cec_workqueue); + } free_dev: v4l2_device_put(&dev->v4l2_dev); return ret; @@ -1331,8 +1425,7 @@ static int vivid_probe(struct platform_device *pdev) static int vivid_remove(struct platform_device *pdev) { struct vivid_dev *dev; - unsigned i; - + unsigned int i, j; for (i = 0; i < n_devs; i++) { dev = vivid_devs[i]; @@ -1380,6 +1473,13 @@ static int vivid_remove(struct platform_device *pdev) unregister_framebuffer(&dev->fb_info); vivid_fb_release_buffers(dev); } + cec_unregister_adapter(dev->cec_rx_adap); + for (j = 0; j < MAX_OUTPUTS; j++) + cec_unregister_adapter(dev->cec_tx_adap[j]); + if (dev->cec_workqueue) { + vivid_cec_bus_free_work(dev); + destroy_workqueue(dev->cec_workqueue); + } v4l2_device_put(&dev->v4l2_dev); vivid_devs[i] = NULL; } diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 776783bec227..a7daa40d0a49 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -21,6 +21,8 @@ #define _VIVID_CORE_H_ #include +#include +#include #include #include #include @@ -132,6 +134,17 @@ enum vivid_colorspace { #define VIVID_INVALID_SIGNAL(mode) \ ((mode) == NO_SIGNAL || (mode) == NO_LOCK || (mode) == OUT_OF_RANGE) +struct vivid_cec_work { + struct list_head list; + struct delayed_work work; + struct cec_adapter *adap; + struct vivid_dev *dev; + unsigned int usecs; + unsigned int timeout_ms; + u8 tx_status; + struct cec_msg msg; +}; + struct vivid_dev { unsigned inst; struct v4l2_device v4l2_dev; @@ -497,6 +510,20 @@ struct vivid_dev { /* Shared between radio receiver and transmitter */ bool radio_rds_loop; struct timespec radio_rds_init_ts; + + /* CEC */ + struct cec_adapter *cec_rx_adap; + struct cec_adapter *cec_tx_adap[MAX_OUTPUTS]; + struct workqueue_struct *cec_workqueue; + spinlock_t cec_slock; + struct list_head cec_work_list; + unsigned int cec_xfer_time_jiffies; + unsigned long cec_xfer_start_jiffies; + u8 cec_output2bus_map[MAX_OUTPUTS]; + + /* CEC OSD String */ + char osd[14]; + unsigned long osd_jiffies; }; static inline bool vivid_is_webcam(const struct vivid_dev *dev) diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c index 3b8c10108dfa..6ca71aabb576 100644 --- a/drivers/media/platform/vivid/vivid-kthread-cap.c +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c @@ -552,6 +552,19 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) snprintf(str, sizeof(str), " button pressed!"); tpg_gen_text(tpg, basep, line++ * line_height, 16, str); } + if (dev->osd[0]) { + if (vivid_is_hdmi_cap(dev)) { + snprintf(str, sizeof(str), + " OSD \"%s\"", dev->osd); + tpg_gen_text(tpg, basep, line++ * line_height, + 16, str); + } + if (dev->osd_jiffies && + time_is_before_jiffies(dev->osd_jiffies + 5 * HZ)) { + dev->osd[0] = 0; + dev->osd_jiffies = 0; + } + } } /* diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 4f730f355a17..16fcac1b560f 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -1701,6 +1701,9 @@ int vidioc_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid) { struct vivid_dev *dev = video_drvdata(file); + u16 phys_addr; + unsigned int i; + int ret; memset(edid->reserved, 0, sizeof(edid->reserved)); if (edid->pad >= dev->num_inputs) @@ -1709,14 +1712,32 @@ int vidioc_s_edid(struct file *file, void *_fh, return -EINVAL; if (edid->blocks == 0) { dev->edid_blocks = 0; - return 0; + phys_addr = CEC_PHYS_ADDR_INVALID; + goto set_phys_addr; } if (edid->blocks > dev->edid_max_blocks) { edid->blocks = dev->edid_max_blocks; return -E2BIG; } + phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); + ret = cec_phys_addr_validate(phys_addr, &phys_addr, NULL); + if (ret) + return ret; + + if (vb2_is_busy(&dev->vb_vid_cap_q)) + return -EBUSY; + dev->edid_blocks = edid->blocks; memcpy(dev->edid, edid->edid, edid->blocks * 128); + +set_phys_addr: + /* TODO: a proper hotplug detect cycle should be emulated here */ + cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false); + + for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) + cec_s_phys_addr(dev->cec_tx_adap[i], + cec_phys_addr_for_input(phys_addr, i + 1), + false); return 0; } diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 39ea2284789c..fcda3ae4e6b0 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -811,6 +811,7 @@ int vidioc_g_edid(struct file *file, void *_fh, { struct vivid_dev *dev = video_drvdata(file); struct video_device *vdev = video_devdata(file); + struct cec_adapter *adap; memset(edid->reserved, 0, sizeof(edid->reserved)); if (vdev->vfl_dir == VFL_DIR_RX) { @@ -818,11 +819,16 @@ int vidioc_g_edid(struct file *file, void *_fh, return -EINVAL; if (dev->input_type[edid->pad] != HDMI) return -EINVAL; + adap = dev->cec_rx_adap; } else { + unsigned int bus_idx; + if (edid->pad >= dev->num_outputs) return -EINVAL; if (dev->output_type[edid->pad] != HDMI) return -EINVAL; + bus_idx = dev->cec_output2bus_map[edid->pad]; + adap = dev->cec_tx_adap[bus_idx]; } if (edid->start_block == 0 && edid->blocks == 0) { edid->blocks = dev->edid_blocks; @@ -835,5 +841,6 @@ int vidioc_g_edid(struct file *file, void *_fh, if (edid->start_block + edid->blocks > dev->edid_blocks) edid->blocks = dev->edid_blocks - edid->start_block; memcpy(edid->edid, dev->edid, edid->blocks * 128); + cec_set_edid_phys_addr(edid->edid, edid->blocks * 128, adap->phys_addr); return 0; } -- cgit v1.3-14-g43fede From c7169ad5616229b87cabf886bc5f9cbd1fc35a5f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Sep 2015 10:12:58 -0300 Subject: [media] DocBook/media: add CEC documentation Add DocBook documentation for the CEC API. Signed-off-by: Hans Verkuil [k.debski@samsung.com: add documentation for passthrough mode] [k.debski@samsung.com: minor fixes and change of reserved field sizes] Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/device-drivers.tmpl | 3 + Documentation/DocBook/media/Makefile | 2 + Documentation/DocBook/media/v4l/biblio.xml | 10 + Documentation/DocBook/media/v4l/cec-api.xml | 75 +++++ Documentation/DocBook/media/v4l/cec-func-close.xml | 64 ++++ Documentation/DocBook/media/v4l/cec-func-ioctl.xml | 78 +++++ Documentation/DocBook/media/v4l/cec-func-open.xml | 104 +++++++ Documentation/DocBook/media/v4l/cec-func-poll.xml | 94 ++++++ .../DocBook/media/v4l/cec-ioc-adap-g-caps.xml | 151 ++++++++++ .../DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml | 329 +++++++++++++++++++++ .../DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml | 86 ++++++ .../DocBook/media/v4l/cec-ioc-dqevent.xml | 202 +++++++++++++ Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml | 255 ++++++++++++++++ .../DocBook/media/v4l/cec-ioc-receive.xml | 274 +++++++++++++++++ Documentation/DocBook/media_api.tmpl | 6 +- 15 files changed, 1732 insertions(+), 1 deletion(-) create mode 100644 Documentation/DocBook/media/v4l/cec-api.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-close.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-ioctl.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-open.xml create mode 100644 Documentation/DocBook/media/v4l/cec-func-poll.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-dqevent.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml create mode 100644 Documentation/DocBook/media/v4l/cec-ioc-receive.xml (limited to 'Documentation') diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index de79efdad46c..a20a45b45c30 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -272,6 +272,9 @@ X!Isound/sound_firmware.c !Iinclude/media/media-devnode.h !Iinclude/media/media-entity.h + Consumer Electronics Control devices +!Iinclude/media/cec-edid.h + diff --git a/Documentation/DocBook/media/Makefile b/Documentation/DocBook/media/Makefile index 2840ff483d5a..fdc138624800 100644 --- a/Documentation/DocBook/media/Makefile +++ b/Documentation/DocBook/media/Makefile @@ -64,6 +64,7 @@ IOCTLS = \ $(shell perl -ne 'print "$$1 " if /\#define\s+([A-Z][^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/dvb/net.h) \ $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/dvb/video.h) \ $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/media.h) \ + $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/linux/cec.h) \ $(shell perl -ne 'print "$$1 " if /\#define\s+([^\s]+)\s+_IO/' $(srctree)/include/uapi/linux/v4l2-subdev.h) \ DEFINES = \ @@ -100,6 +101,7 @@ STRUCTS = \ $(shell perl -ne 'print "$$1 " if (/^struct\s+([^\s]+)\s+/ && !/_old/)' $(srctree)/include/uapi/linux/dvb/net.h) \ $(shell perl -ne 'print "$$1 " if (/^struct\s+([^\s]+)\s+/)' $(srctree)/include/uapi/linux/dvb/video.h) \ $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/uapi/linux/media.h) \ + $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/linux/cec.h) \ $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/uapi/linux/v4l2-subdev.h) \ $(shell perl -ne 'print "$$1 " if /^struct\s+([^\s]+)\s+/' $(srctree)/include/uapi/linux/v4l2-mediabus.h) diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml index 9beb30f0071b..87f1d24958aa 100644 --- a/Documentation/DocBook/media/v4l/biblio.xml +++ b/Documentation/DocBook/media/v4l/biblio.xml @@ -342,6 +342,16 @@ in the frequency range from 87,5 to 108,0 MHz Specification Version 1.4a + + HDMI2 + + HDMI Licensing LLC +(http://www.hdmi.org) + + High-Definition Multimedia Interface + Specification Version 2.0 + + DP diff --git a/Documentation/DocBook/media/v4l/cec-api.xml b/Documentation/DocBook/media/v4l/cec-api.xml new file mode 100644 index 000000000000..7062c1fa4904 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-api.xml @@ -0,0 +1,75 @@ + + + + Hans + Verkuil +
hans.verkuil@cisco.com
+ Initial version. +
+
+ + 2016 + Hans Verkuil + + + + + + 1.0.0 + 2016-03-17 + hv + Initial revision + + +
+ +CEC API + + + CEC: Consumer Electronics Control + +
+ Introduction + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + HDMI connectors provide a single pin for use by the Consumer Electronics + Control protocol. This protocol allows different devices connected by an HDMI cable + to communicate. The protocol for CEC version 1.4 is defined in supplements 1 (CEC) + and 2 (HEAC or HDMI Ethernet and Audio Return Channel) of the HDMI 1.4a + () specification and the extensions added to CEC version 2.0 + are defined in chapter 11 of the HDMI 2.0 () specification. + + + The bitrate is very slow (effectively no more than 36 bytes per second) and + is based on the ancient AV.link protocol used in old SCART connectors. The protocol + closely resembles a crazy Rube Goldberg contraption and is an unholy mix of low and + high level messages. Some messages, especially those part of the HEAC protocol layered + on top of CEC, need to be handled by the kernel, others can be handled either by the + kernel or by userspace. + + In addition, CEC can be implemented in HDMI receivers, transmitters and in USB + devices that have an HDMI input and an HDMI output and that control just the CEC pin. + + Drivers that support CEC will create a CEC device node (/dev/cecX) + to give userspace access to the CEC adapter. The &CEC-ADAP-G-CAPS; ioctl will tell userspace + what it is allowed to do. +
+
+ + + Function Reference + + &sub-cec-func-open; + &sub-cec-func-close; + &sub-cec-func-ioctl; + &sub-cec-func-poll; + + &sub-cec-ioc-adap-g-caps; + &sub-cec-ioc-adap-g-log-addrs; + &sub-cec-ioc-adap-g-phys-addr; + &sub-cec-ioc-dqevent; + &sub-cec-ioc-g-mode; + &sub-cec-ioc-receive; + diff --git a/Documentation/DocBook/media/v4l/cec-func-close.xml b/Documentation/DocBook/media/v4l/cec-func-close.xml new file mode 100644 index 000000000000..0812c8cd9634 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-func-close.xml @@ -0,0 +1,64 @@ + + + cec close() + &manvol; + + + + cec-close + Close a cec device + + + + + #include <unistd.h> + + int close + int fd + + + + + + Arguments + + + + fd + + &fd; + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + Closes the cec device. Resources associated with the file descriptor + are freed. The device configuration remain unchanged. + + + + Return Value + + close returns 0 on success. On error, -1 is + returned, and errno is set appropriately. Possible error + codes are: + + + + EBADF + + fd is not a valid open file descriptor. + + + + + + diff --git a/Documentation/DocBook/media/v4l/cec-func-ioctl.xml b/Documentation/DocBook/media/v4l/cec-func-ioctl.xml new file mode 100644 index 000000000000..f92817a2dc80 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-func-ioctl.xml @@ -0,0 +1,78 @@ + + + cec ioctl() + &manvol; + + + + cec-ioctl + Control a cec device + + + + + #include <sys/ioctl.h> + + int ioctl + int fd + int request + void *argp + + + + + + Arguments + + + + fd + + &fd; + + + + request + + CEC ioctl request code as defined in the cec.h header file, + for example CEC_ADAP_G_CAPS. + + + + argp + + Pointer to a request-specific structure. + + + + + + + Description + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + The ioctl() function manipulates cec device + parameters. The argument fd must be an open file + descriptor. + The ioctl request code specifies the cec + function to be called. It has encoded in it whether the argument is an + input, output or read/write parameter, and the size of the argument + argp in bytes. + Macros and structures definitions specifying cec ioctl requests and + their parameters are located in the cec.h header file. All cec ioctl + requests, their respective function and parameters are specified in + . + + + + &return-value; + + Request-specific error codes are listed in the + individual requests descriptions. + When an ioctl that takes an output or read/write parameter fails, + the parameter remains unmodified. + + diff --git a/Documentation/DocBook/media/v4l/cec-func-open.xml b/Documentation/DocBook/media/v4l/cec-func-open.xml new file mode 100644 index 000000000000..2edc5555b81a --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-func-open.xml @@ -0,0 +1,104 @@ + + + cec open() + &manvol; + + + + cec-open + Open a cec device + + + + + #include <fcntl.h> + + int open + const char *device_name + int flags + + + + + + Arguments + + + + device_name + + Device to be opened. + + + + flags + + Open flags. Access mode must be O_RDWR. + + When the O_NONBLOCK flag is +given, the &CEC-RECEIVE; ioctl will return &EAGAIN; when no message is +available, and the &CEC-TRANSMIT;, &CEC-ADAP-S-PHYS-ADDR; and +&CEC-ADAP-S-LOG-ADDRS; ioctls all act in non-blocking mode. + Other flags have no effect. + + + + + + Description + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + To open a cec device applications call open() + with the desired device name. The function has no side effects; the device + configuration remain unchanged. + When the device is opened in read-only mode, attempts to modify its + configuration will result in an error, and errno will be + set to EBADF. + + + Return Value + + open returns the new file descriptor on success. + On error, -1 is returned, and errno is set appropriately. + Possible error codes include: + + + + EACCES + + The requested access to the file is not allowed. + + + + EMFILE + + The process already has the maximum number of files open. + + + + + ENFILE + + The system limit on the total number of open files has been + reached. + + + + ENOMEM + + Insufficient kernel memory was available. + + + + ENXIO + + No device corresponding to this device special file exists. + + + + + + diff --git a/Documentation/DocBook/media/v4l/cec-func-poll.xml b/Documentation/DocBook/media/v4l/cec-func-poll.xml new file mode 100644 index 000000000000..1bddbde0142d --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-func-poll.xml @@ -0,0 +1,94 @@ + + + cec poll() + &manvol; + + + + cec-poll + Wait for some event on a file descriptor + + + + + #include <sys/poll.h> + + int poll + struct pollfd *ufds + unsigned int nfds + int timeout + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + With the poll() function applications +can wait for CEC events. + + On success poll() returns the number of +file descriptors that have been selected (that is, file descriptors +for which the revents field of the +respective pollfd structure is non-zero). +CEC devices set the POLLIN and +POLLRDNORM flags in the +revents field if there are messages in the +receive queue. If the transmit queue has room for new messages, the +POLLOUT and POLLWRNORM +flags are set. If there are events in the event queue, then the +POLLPRI flag is set. +When the function timed out it returns a value of zero, on +failure it returns -1 and the +errno variable is set appropriately. + + + For more details see the +poll() manual page. + + + + Return Value + + On success, poll() returns the number +structures which have non-zero revents +fields, or zero if the call timed out. On error +-1 is returned, and the +errno variable is set appropriately: + + + + EBADF + + One or more of the ufds members +specify an invalid file descriptor. + + + + EFAULT + + ufds references an inaccessible +memory area. + + + + EINTR + + The call was interrupted by a signal. + + + + EINVAL + + The nfds argument is greater +than OPEN_MAX. + + + + + diff --git a/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml new file mode 100644 index 000000000000..3523ef2259b1 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-caps.xml @@ -0,0 +1,151 @@ + + + ioctl CEC_ADAP_G_CAPS + &manvol; + + + + CEC_ADAP_G_CAPS + Query device capabilities + + + + + + int ioctl + int fd + int request + struct cec_caps *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + CEC_ADAP_G_CAPS + + + + argp + + + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + All cec devices must support the CEC_ADAP_G_CAPS + ioctl. To query device information, applications call the ioctl with a + pointer to a &cec-caps;. The driver fills the structure and returns + the information to the application. + The ioctl never fails. + + + struct <structname>cec_caps</structname> + + &cs-str; + + + char + driver[32] + The name of the cec adapter driver. + + + char + name[32] + The name of this CEC adapter. The combination driver + and name must be unique. + + + __u32 + capabilities + The capabilities of the CEC adapter, see . + + + __u32 + version + CEC Framework API version, formatted with the + KERNEL_VERSION() macro. + + + +
+ + + CEC Capabilities Flags + + &cs-def; + + + CEC_CAP_PHYS_ADDR + 0x00000001 + Userspace has to configure the physical address by + calling &CEC-ADAP-S-PHYS-ADDR;. If this capability isn't set, + then setting the physical address is handled by the kernel + whenever the EDID is set (for an HDMI receiver) or read (for + an HDMI transmitter). + + + CEC_CAP_LOG_ADDRS + 0x00000002 + Userspace has to configure the logical addresses by + calling &CEC-ADAP-S-LOG-ADDRS;. If this capability isn't set, + then the kernel will have configured this. + + + CEC_CAP_TRANSMIT + 0x00000004 + Userspace can transmit CEC messages by calling &CEC-TRANSMIT;. This + implies that userspace can be a follower as well, since being able to + transmit messages is a prerequisite of becoming a follower. If this + capability isn't set, then the kernel will handle all CEC transmits + and process all CEC messages it receives. + + + + CEC_CAP_PASSTHROUGH + 0x00000008 + Userspace can use the passthrough mode by + calling &CEC-S-MODE;. + + + CEC_CAP_RC + 0x00000010 + This adapter supports the remote control protocol. + + + CEC_CAP_MONITOR_ALL + 0x00000020 + The CEC hardware can monitor all messages, not just directed and + broadcast messages. + + + +
+
+ + + &return-value; + +
diff --git a/Documentation/DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml new file mode 100644 index 000000000000..302b8294f7fc --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-log-addrs.xml @@ -0,0 +1,329 @@ + + + ioctl CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS + &manvol; + + + + CEC_ADAP_G_LOG_ADDRS + CEC_ADAP_S_LOG_ADDRS + Get or set the logical addresses + + + + + + int ioctl + int fd + int request + struct cec_log_addrs *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS + + + + argp + + + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + To query the current CEC logical addresses, applications call the +CEC_ADAP_G_LOG_ADDRS ioctl with a pointer to a +cec_log_addrs structure where the drivers stores the +logical addresses. + + To set new logical addresses, applications fill in struct cec_log_addrs +and call the CEC_ADAP_S_LOG_ADDRS ioctl with a pointer to this struct. +The CEC_ADAP_S_LOG_ADDRS ioctl is only available if +CEC_CAP_LOG_ADDRS is set (&ENOTTY; is returned otherwise). This ioctl will block until all +requested logical addresses have been claimed. CEC_ADAP_S_LOG_ADDRS +can only be called by a file handle in initiator mode (see &CEC-S-MODE;). + + + struct <structname>cec_log_addrs</structname> + + &cs-str; + + + __u8 + log_addr[CEC_MAX_LOG_ADDRS] + The actual logical addresses that were claimed. This is set by the + driver. If no logical address could be claimed, then it is set to + CEC_LOG_ADDR_INVALID. If this adapter is Unregistered, + then log_addr[0] is set to 0xf and all others to + CEC_LOG_ADDR_INVALID. + + + __u16 + log_addr_mask + The bitmask of all logical addresses this adapter has claimed. + If this adapter is Unregistered then log_addr_mask + sets bit 15 and clears all other bits. If this adapter is not configured at all, then + log_addr_mask is set to 0. Set by the driver. + + + __u8 + cec_version + The CEC version that this adapter shall use. See + . + Used to implement the CEC_MSG_CEC_VERSION and + CEC_MSG_REPORT_FEATURES messages. Note that + CEC_OP_CEC_VERSION_1_3A is not allowed + by the CEC framework. + + + + __u8 + num_log_addrs + Number of logical addresses to set up. Must be ≤ + available_log_addrs as returned by + &CEC-ADAP-G-CAPS;. All arrays in this structure are only filled up to + index available_log_addrs-1. The remaining + array elements will be ignored. Note that the CEC 2.0 standard allows + for a maximum of 2 logical addresses, although some hardware has support + for more. CEC_MAX_LOG_ADDRS is 4. The driver will + return the actual number of logical addresses it could claim, which may + be less than what was requested. If this field is set to 0, then the + CEC adapter shall clear all claimed logical addresses and all other + fields will be ignored. + + + __u32 + vendor_id + The vendor ID is a 24-bit number that identifies the specific + vendor or entity. Based on this ID vendor specific commands may be + defined. If you do not want a vendor ID then set it to + CEC_VENDOR_ID_NONE. + + + __u32 + flags + Flags. No flags are defined yet, so set this to 0. + + + char + osd_name[15] + The On-Screen Display name as is returned by the + CEC_MSG_SET_OSD_NAME message. + + + __u8 + primary_device_type[CEC_MAX_LOG_ADDRS] + Primary device type for each logical address. See + for possible types. + + + __u8 + log_addr_type[CEC_MAX_LOG_ADDRS] + Logical address types. See for + possible types. The driver will update this with the actual logical address + type that it claimed (e.g. it may have to fallback to + CEC_LOG_ADDR_TYPE_UNREGISTERED). + + + __u8 + all_device_types[CEC_MAX_LOG_ADDRS] + CEC 2.0 specific: all device types. See . + Used to implement the CEC_MSG_REPORT_FEATURES message. + This field is ignored if cec_version < + CEC_OP_CEC_VERSION_2_0. + + + __u8 + features[CEC_MAX_LOG_ADDRS][12] + Features for each logical address. Used to implement the + CEC_MSG_REPORT_FEATURES message. The 12 bytes include + both the RC Profile and the Device Features. + This field is ignored if cec_version < + CEC_OP_CEC_VERSION_2_0. + + + +
+ + + CEC Versions + + &cs-def; + + + CEC_OP_CEC_VERSION_1_3A + 4 + CEC version according to the HDMI 1.3a standard. + + + CEC_OP_CEC_VERSION_1_4B + 5 + CEC version according to the HDMI 1.4b standard. + + + CEC_OP_CEC_VERSION_2_0 + 6 + CEC version according to the HDMI 2.0 standard. + + + +
+ + + CEC Primary Device Types + + &cs-def; + + + CEC_OP_PRIM_DEVTYPE_TV + 0 + Use for a TV. + + + CEC_OP_PRIM_DEVTYPE_RECORD + 1 + Use for a recording device. + + + CEC_OP_PRIM_DEVTYPE_TUNER + 3 + Use for a device with a tuner. + + + CEC_OP_PRIM_DEVTYPE_PLAYBACK + 4 + Use for a playback device. + + + CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM + 5 + Use for an audio system (e.g. an audio/video receiver). + + + CEC_OP_PRIM_DEVTYPE_SWITCH + 6 + Use for a CEC switch. + + + CEC_OP_PRIM_DEVTYPE_VIDEOPROC + 7 + Use for a video processor device. + + + +
+ + + CEC Logical Address Types + + &cs-def; + + + CEC_LOG_ADDR_TYPE_TV + 0 + Use for a TV. + + + CEC_LOG_ADDR_TYPE_RECORD + 1 + Use for a recording device. + + + CEC_LOG_ADDR_TYPE_TUNER + 2 + Use for a tuner device. + + + CEC_LOG_ADDR_TYPE_PLAYBACK + 3 + Use for a playback device. + + + CEC_LOG_ADDR_TYPE_AUDIOSYSTEM + 4 + Use for an audio system device. + + + CEC_LOG_ADDR_TYPE_SPECIFIC + 5 + Use for a second TV or for a video processor device. + + + CEC_LOG_ADDR_TYPE_UNREGISTERED + 6 + Use this if you just want to remain unregistered. + Used for pure CEC switches or CDC-only devices (CDC: + Capability Discovery and Control). + + + +
+ + + CEC All Device Types Flags + + &cs-def; + + + CEC_OP_ALL_DEVTYPE_TV + 0x80 + This supports the TV type. + + + CEC_OP_ALL_DEVTYPE_RECORD + 0x40 + This supports the Recording type. + + + CEC_OP_ALL_DEVTYPE_TUNER + 0x20 + This supports the Tuner type. + + + CEC_OP_ALL_DEVTYPE_PLAYBACK + 0x10 + This supports the Playback type. + + + CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM + 0x08 + This supports the Audio System type. + + + CEC_OP_ALL_DEVTYPE_SWITCH + 0x04 + This supports the CEC Switch or Video Processing type. + + + +
+
+ + + &return-value; + +
diff --git a/Documentation/DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml new file mode 100644 index 000000000000..d95f1785080c --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-ioc-adap-g-phys-addr.xml @@ -0,0 +1,86 @@ + + + ioctl CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR + &manvol; + + + + CEC_ADAP_G_PHYS_ADDR + CEC_ADAP_S_PHYS_ADDR + Get or set the physical address + + + + + + int ioctl + int fd + int request + __u16 *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR + + + + argp + + + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + To query the current physical address applications call the +CEC_ADAP_G_PHYS_ADDR ioctl with a pointer to an __u16 +where the driver stores the physical address. + + To set a new physical address applications store the physical address in +an __u16 and call the CEC_ADAP_S_PHYS_ADDR ioctl with a +pointer to this integer. CEC_ADAP_S_PHYS_ADDR is only +available if CEC_CAP_PHYS_ADDR is set (&ENOTTY; will be returned +otherwise). CEC_ADAP_S_PHYS_ADDR +can only be called by a file handle in initiator mode (see &CEC-S-MODE;), if not +&EBUSY; will be returned. + + The physical address is a 16-bit number where each group of 4 bits +represent a digit of the physical address a.b.c.d where the most significant +4 bits represent 'a'. The CEC root device (usually the TV) has address 0.0.0.0. +Every device that is hooked up to an input of the TV has address a.0.0.0 (where +'a' is ≥ 1), devices hooked up to those in turn have addresses a.b.0.0, etc. +So a topology of up to 5 devices deep is supported. The physical address a +device shall use is stored in the EDID of the sink. + +For example, the EDID for each HDMI input of the TV will have a different +physical address of the form a.0.0.0 that the sources will read out and use as +their physical address. + + + + &return-value; + + diff --git a/Documentation/DocBook/media/v4l/cec-ioc-dqevent.xml b/Documentation/DocBook/media/v4l/cec-ioc-dqevent.xml new file mode 100644 index 000000000000..697dde575cd4 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-ioc-dqevent.xml @@ -0,0 +1,202 @@ + + + ioctl CEC_DQEVENT + &manvol; + + + + CEC_DQEVENT + Dequeue a CEC event + + + + + + int ioctl + int fd + int request + struct cec_event *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + CEC_DQEVENT + + + + argp + + + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + CEC devices can send asynchronous events. These can be retrieved by calling + the CEC_DQEVENT ioctl. If the file descriptor is in non-blocking + mode and no event is pending, then it will return -1 and set errno to the &EAGAIN;. + + The internal event queues are per-filehandle and per-event type. If there is + no more room in a queue then the last event is overwritten with the new one. This + means that intermediate results can be thrown away but that the latest event is always + available. This also means that is it possible to read two successive events that have + the same value (e.g. two CEC_EVENT_STATE_CHANGE events with the same state). In that + case the intermediate state changes were lost but it is guaranteed that the state + did change in between the two events. + + + struct <structname>cec_event_state_change</structname> + + &cs-str; + + + __u16 + phys_addr + The current physical address. + + + __u16 + log_addr_mask + The current set of claimed logical addresses. + + + +
+ + + struct <structname>cec_event_lost_msgs</structname> + + &cs-str; + + + __u32 + lost_msgs + Set to the number of lost messages since the filehandle + was opened or since the last time this event was dequeued for + this filehandle. The messages lost are the oldest messages. So + when a new message arrives and there is no more room, then the + oldest message is discarded to make room for the new one. The + internal size of the message queue guarantees that all messages + received in the last two seconds will be stored. Since messages + should be replied to within a second according to the CEC + specification, this is more than enough. + + + + +
+ + + struct <structname>cec_event</structname> + + &cs-str; + + + __u64 + ts + Timestamp of the event in ns. + + + + __u32 + event + The CEC event type, see . + + + + __u32 + flags + Event flags, see . + + + + union + (anonymous) + + + + + + struct cec_event_state_change + state_change + The new adapter state as sent by the CEC_EVENT_STATE_CHANGE + event. + + + + struct cec_event_lost_msgs + lost_msgs + The number of lost messages as sent by the CEC_EVENT_LOST_MSGS + event. + + + +
+ + + CEC Events Types + + &cs-def; + + + CEC_EVENT_STATE_CHANGE + 1 + Generated when the CEC Adapter's state changes. When open() is + called an initial event will be generated for that filehandle with the + CEC Adapter's state at that time. + + + + CEC_EVENT_LOST_MSGS + 2 + Generated if one or more CEC messages were lost because the + application didn't dequeue CEC messages fast enough. + + + +
+ + + CEC Event Flags + + &cs-def; + + + CEC_EVENT_FL_INITIAL_VALUE + 1 + Set for the initial events that are generated when the device is + opened. See the table above for which events do this. This allows + applications to learn the initial state of the CEC adapter at open() + time. + + + +
+
+ + + &return-value; + +
diff --git a/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml b/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml new file mode 100644 index 000000000000..26b4282ad134 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-ioc-g-mode.xml @@ -0,0 +1,255 @@ + + + ioctl CEC_G_MODE, CEC_S_MODE + &manvol; + + + + CEC_G_MODE + CEC_S_MODE + Get or set exclusive use of the CEC adapter + + + + + + int ioctl + int fd + int request + __u32 *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + CEC_G_MODE, CEC_S_MODE + + + + argp + + + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + By default any filehandle can use &CEC-TRANSMIT; and &CEC-RECEIVE;, but +in order to prevent applications from stepping on each others toes it must be possible +to obtain exclusive access to the CEC adapter. This ioctl sets the filehandle +to initiator and/or follower mode which can be exclusive depending on the chosen +mode. The initiator is the filehandle that is used +to initiate messages, i.e. it commands other CEC devices. The follower is the filehandle +that receives messages sent to the CEC adapter and processes them. The same filehandle +can be both initiator and follower, or this role can be taken by two different +filehandles. + + When a CEC message is received, then the CEC framework will decide how +it will be processed. If the message is a reply to an earlier transmitted message, +then the reply is sent back to the filehandle that is waiting for it. In addition +the CEC framework will process it. + + If the message is not a reply, then the CEC framework will process it +first. If there is no follower, then the message is just discarded and a feature +abort is sent back to the initiator if the framework couldn't process it. If there +is a follower, then the message is passed on to the follower who will use +&CEC-RECEIVE; to dequeue the new message. The framework expects the follower to +make the right decisions. + + The CEC framework will process core messages unless requested otherwise +by the follower. The follower can enable the passthrough mode. In that case, the +CEC framework will pass on most core messages without processing them and +the follower will have to implement those messages. There are some messages +that the core will always process, regardless of the passthrough mode. See + for details. + + If there is no initiator, then any CEC filehandle can use &CEC-TRANSMIT;. +If there is an exclusive initiator then only that initiator can call &CEC-TRANSMIT;. +The follower can of course always call &CEC-TRANSMIT;. + + Available initiator modes are: + + + Initiator Modes + + &cs-def; + + + CEC_MODE_NO_INITIATOR + 0x0 + This is not an initiator, i.e. it cannot transmit CEC messages + or make any other changes to the CEC adapter. + + + CEC_MODE_INITIATOR + 0x1 + This is an initiator (the default when the device is opened) and it + can transmit CEC messages and make changes to the CEC adapter, unless there + is an exclusive initiator. + + + CEC_MODE_EXCL_INITIATOR + 0x2 + This is an exclusive initiator and this file descriptor is the only one + that can transmit CEC messages and make changes to the CEC adapter. If someone + else is already the exclusive initiator then an attempt to become one will return + the &EBUSY; error. + + + +
+ + Available follower modes are: + + + Follower Modes + + &cs-def; + + + CEC_MODE_NO_FOLLOWER + 0x00 + This is not a follower (the default when the device is opened). + + + CEC_MODE_FOLLOWER + 0x10 + This is a follower and it will receive CEC messages unless there is + an exclusive follower. You cannot become a follower if CEC_CAP_TRANSMIT + is not set or if CEC_MODE_NO_INITIATOR was specified, + &EINVAL; is returned in that case. + + + CEC_MODE_EXCL_FOLLOWER + 0x20 + This is an exclusive follower and only this file descriptor will receive + CEC messages for processing. If someone else is already the exclusive follower + then an attempt to become one will return the &EBUSY; error. You cannot become + a follower if CEC_CAP_TRANSMIT is not set or if + CEC_MODE_NO_INITIATOR was specified, &EINVAL; is returned + in that case. + + + CEC_MODE_EXCL_FOLLOWER_PASSTHRU + 0x30 + This is an exclusive follower and only this file descriptor will receive + CEC messages for processing. In addition it will put the CEC device into + passthrough mode, allowing the exclusive follower to handle most core messages + instead of relying on the CEC framework for that. If someone else is already the + exclusive follower then an attempt to become one will return the &EBUSY; error. + You cannot become a follower if CEC_CAP_TRANSMIT + is not set or if CEC_MODE_NO_INITIATOR was specified, + &EINVAL; is returned in that case. + + + CEC_MODE_MONITOR + 0xe0 + Put the file descriptor into monitor mode. Can only be used in combination + with CEC_MODE_NO_INITIATOR, otherwise &EINVAL; will be + returned. In monitor mode all messages this CEC device transmits and all messages + it receives (both broadcast messages and directed messages for one its logical + addresses) will be reported. This is very useful for debugging. This is only + allowed if the process has the CAP_NET_ADMIN + capability. If that is not set, then &EPERM; is returned. + + + CEC_MODE_MONITOR_ALL + 0xf0 + Put the file descriptor into 'monitor all' mode. Can only be used in combination + with CEC_MODE_NO_INITIATOR, otherwise &EINVAL; will be + returned. In 'monitor all' mode all messages this CEC device transmits and all messages + it receives, including directed messages for other CEC devices will be reported. This + is very useful for debugging, but not all devices support this. This mode requires that + the CEC_CAP_MONITOR_ALL capability is set, otherwise &EINVAL; is + returned. This is only allowed if the process has the CAP_NET_ADMIN + capability. If that is not set, then &EPERM; is returned. + + + +
+ + Core message processing details: + + + Core Message Processing + + &cs-def; + + + CEC_MSG_GET_CEC_VERSION + When in passthrough mode this message has to be handled by userspace, + otherwise the core will return the CEC version that was set with &CEC-ADAP-S-LOG-ADDRS;. + + + CEC_MSG_GIVE_DEVICE_VENDOR_ID + When in passthrough mode this message has to be handled by userspace, + otherwise the core will return the vendor ID that was set with &CEC-ADAP-S-LOG-ADDRS;. + + + CEC_MSG_ABORT + When in passthrough mode this message has to be handled by userspace, + otherwise the core will return a feature refused message as per the specification. + + + CEC_MSG_GIVE_PHYSICAL_ADDR + When in passthrough mode this message has to be handled by userspace, + otherwise the core will report the current physical address. + + + CEC_MSG_GIVE_OSD_NAME + When in passthrough mode this message has to be handled by userspace, + otherwise the core will report the current OSD name as was set with + &CEC-ADAP-S-LOG-ADDRS;. + + + CEC_MSG_GIVE_FEATURES + When in passthrough mode this message has to be handled by userspace, + otherwise the core will report the current features as was set with + &CEC-ADAP-S-LOG-ADDRS; or the message is ignore if the CEC version was + older than 2.0. + + + CEC_MSG_USER_CONTROL_PRESSED + If CEC_CAP_RC is set, then generate a remote control + key press. This message is always passed on to userspace. + + + CEC_MSG_USER_CONTROL_RELEASED + If CEC_CAP_RC is set, then generate a remote control + key release. This message is always passed on to userspace. + + + CEC_MSG_REPORT_PHYSICAL_ADDR + The CEC framework will make note of the reported physical address + and then just pass the message on to userspace. + + + +
+
+ + + &return-value; + +
diff --git a/Documentation/DocBook/media/v4l/cec-ioc-receive.xml b/Documentation/DocBook/media/v4l/cec-ioc-receive.xml new file mode 100644 index 000000000000..fde9f8678e67 --- /dev/null +++ b/Documentation/DocBook/media/v4l/cec-ioc-receive.xml @@ -0,0 +1,274 @@ + + + ioctl CEC_RECEIVE, CEC_TRANSMIT + &manvol; + + + + CEC_RECEIVE + CEC_TRANSMIT + Receive or transmit a CEC message + + + + + + int ioctl + int fd + int request + struct cec_msg *argp + + + + + + Arguments + + + + fd + + File descriptor returned by + open(). + + + + request + + CEC_RECEIVE, CEC_TRANSMIT + + + + argp + + + + + + + + + Description + + + Note: this documents the proposed CEC API. This API is not yet finalized and + is currently only available as a staging kernel module. + + + To receive a CEC message the application has to fill in the + cec_msg structure and pass it to the + CEC_RECEIVE ioctl. CEC_RECEIVE is + only available if CEC_CAP_RECEIVE is set. If the + file descriptor is in non-blocking mode and there are no received + messages pending, then it will return -1 and set errno to the &EAGAIN;. + If the file descriptor is in blocking mode and timeout + is non-zero and no message arrived within timeout + milliseconds, then it will return -1 and set errno to the &ETIMEDOUT;. + + To send a CEC message the application has to fill in the + cec_msg structure and pass it to the + CEC_TRANSMIT ioctl. CEC_TRANSMIT is + only available if CEC_CAP_TRANSMIT is set. + If there is no more room in the transmit queue, then it will return + -1 and set errno to the &EBUSY;. + + + struct <structname>cec_msg</structname> + + &cs-str; + + + __u64 + ts + Timestamp of when the message was transmitted in ns in the case + of CEC_TRANSMIT with reply + set to 0, or the timestamp of the received message in all other cases. + + + __u32 + len + The length of the message. For CEC_TRANSMIT this + is filled in by the application. The driver will fill this in for + CEC_RECEIVE and for CEC_TRANSMIT + it will be filled in with the length of the reply message if + reply was set. + + + __u32 + timeout + The timeout in milliseconds. This is the time the device will wait for a message to + be received before timing out. If it is set to 0, then it will wait indefinitely when it + is called by CEC_RECEIVE. If it is 0 and it is called by + CEC_TRANSMIT, then it will be replaced by 1000 if the + reply is non-zero or ignored if reply + is 0. + + + __u32 + sequence + The sequence number is automatically assigned by the CEC + framework for all transmitted messages. It can be later used by the + framework to generate an event if a reply for a message was + requested and the message was transmitted in a non-blocking mode. + + + + __u32 + flags + Flags. No flags are defined yet, so set this to 0. + + + __u8 + rx_status + The status bits of the received message. See + for the possible status values. It is 0 if this message was transmitted, not + received, unless this is the reply to a transmitted message. In that case both + rx_status and tx_status + are set. + + + __u8 + tx_status + The status bits of the transmitted message. See + for the possible status values. It is 0 if this messages was received, not + transmitted. + + + __u8 + msg[16] + The message payload. For CEC_TRANSMIT this + is filled in by the application. The driver will fill this in for + CEC_RECEIVE and for CEC_TRANSMIT + it will be filled in with the payload of the reply message if + reply was set. + + + __u8 + reply + Wait until this message is replied. If reply + is 0 and the timeout is 0, then don't wait for a reply but + return after transmitting the message. If there was an error as indicated by a non-zero + tx_status field, then reply and + timeout are both set to 0 by the driver. Ignored by + CEC_RECEIVE. The case where reply is 0 + (this is the opcode for the Feature Abort message) and timeout + is non-zero is specifically allowed to send a message and wait up to timeout + milliseconds for a Feature Abort reply. In this case rx_status + will either be set to CEC_RX_STATUS_TIMEOUT or + CEC_RX_STATUS_FEATURE_ABORT. + + + __u8 + tx_arb_lost_cnt + A counter of the number of transmit attempts that resulted in the + Arbitration Lost error. This is only set if the hardware supports this, otherwise + it is always 0. This counter is only valid if the CEC_TX_STATUS_ARB_LOST + status bit is set. + + + __u8 + tx_nack_cnt + A counter of the number of transmit attempts that resulted in the + Not Acknowledged error. This is only set if the hardware supports this, otherwise + it is always 0. This counter is only valid if the CEC_TX_STATUS_NACK + status bit is set. + + + __u8 + tx_low_drive_cnt + A counter of the number of transmit attempts that resulted in the + Arbitration Lost error. This is only set if the hardware supports this, otherwise + it is always 0. This counter is only valid if the CEC_TX_STATUS_LOW_DRIVE + status bit is set. + + + __u8 + tx_error_cnt + A counter of the number of transmit errors other than Arbitration Lost + or Not Acknowledged. This is only set if the hardware supports this, otherwise + it is always 0. This counter is only valid if the CEC_TX_STATUS_ERROR + status bit is set. + + + +
+ + + CEC Transmit Status + + &cs-def; + + + CEC_TX_STATUS_OK + 0x01 + The message was transmitted successfully. This is mutually exclusive with + CEC_TX_STATUS_MAX_RETRIES. Other bits can still be set if + earlier attempts met with failure before the transmit was eventually successful. + + + CEC_TX_STATUS_ARB_LOST + 0x02 + CEC line arbitration was lost. + + + CEC_TX_STATUS_NACK + 0x04 + Message was not acknowledged. + + + CEC_TX_STATUS_LOW_DRIVE + 0x08 + Low drive was detected on the CEC bus. This indicates that a follower + detected an error on the bus and requests a retransmission. + + + CEC_TX_STATUS_ERROR + 0x10 + Some error occurred. This is used for any errors that do not + fit the previous two, either because the hardware could not tell + which error occurred, or because the hardware tested for other conditions + besides those two. + + + CEC_TX_STATUS_MAX_RETRIES + 0x20 + The transmit failed after one or more retries. This status bit is mutually + exclusive with CEC_TX_STATUS_OK. Other bits can still be set + to explain which failures were seen. + + + +
+ + + CEC Receive Status + + &cs-def; + + + CEC_RX_STATUS_OK + 0x01 + The message was received successfully. + + + CEC_RX_STATUS_TIMEOUT + 0x02 + The reply to an earlier transmitted message timed out. + + + CEC_RX_STATUS_FEATURE_ABORT + 0x04 + The message was received successfully but the reply was + CEC_MSG_FEATURE_ABORT. This status is only + set if this message was the reply to an earlier transmitted + message. + + + +
+
+ + + &return-value; + +
diff --git a/Documentation/DocBook/media_api.tmpl b/Documentation/DocBook/media_api.tmpl index 7b77e0f7b87d..a2765d8ad05c 100644 --- a/Documentation/DocBook/media_api.tmpl +++ b/Documentation/DocBook/media_api.tmpl @@ -75,7 +75,7 @@ The media infrastructure API was designed to control such - devices. It is divided into four parts. + devices. It is divided into five parts. The first part covers radio, video capture and output, cameras, analog TV devices and codecs. The second part covers the @@ -87,6 +87,7 @@ . The third part covers the Remote Controller API. The fourth part covers the Media Controller API. + The fifth part covers the CEC (Consumer Electronics Control) API. It should also be noted that a media device may also have audio components, like mixers, PCM capture, PCM playback, etc, which are controlled via ALSA API. @@ -107,6 +108,9 @@ &sub-media-controller; + +&sub-cec-api; + &sub-gen-errors; -- cgit v1.3-14-g43fede From 1179aab13db3c6251484afe492c8dbd869ca8b05 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 15 Feb 2016 22:00:30 -0200 Subject: [media] media: Add video processing entity functions Add composer, pixel formatter, pixel encoding converter and scaler functions. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/media-types.xml | 55 +++++++++++++++++++++++++ include/uapi/linux/media.h | 9 ++++ 2 files changed, 64 insertions(+) (limited to 'Documentation') diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml index 5e3f20fdcf17..60fe841f8846 100644 --- a/Documentation/DocBook/media/v4l/media-types.xml +++ b/Documentation/DocBook/media/v4l/media-types.xml @@ -121,6 +121,61 @@ MEDIA_ENT_F_AUDIO_MIXER Audio Mixer Function Entity. + + MEDIA_ENT_F_PROC_VIDEO_COMPOSER + Video composer (blender). An entity capable of video + composing must have at least two sink pads and one source + pad, and composes input video frames onto output video + frames. Composition can be performed using alpha blending, + color keying, raster operations (ROP), stitching or any other + means. + + + + MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER + Video pixel formatter. An entity capable of pixel formatting + must have at least one sink pad and one source pad. Read + pixel formatters read pixels from memory and perform a subset + of unpacking, cropping, color keying, alpha multiplication + and pixel encoding conversion. Write pixel formatters perform + a subset of dithering, pixel encoding conversion and packing + and write pixels to memory. + + + + MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV + Video pixel encoding converter. An entity capable of pixel + enconding conversion must have at least one sink pad and one + source pad, and convert the encoding of pixels received on + its sink pad(s) to a different encoding output on its source + pad(s). Pixel encoding conversion includes but isn't limited + to RGB to/from HSV, RGB to/from YUV and CFA (Bayer) to RGB + conversions. + + + + MEDIA_ENT_F_PROC_VIDEO_LUT + Video look-up table. An entity capable of video lookup table + processing must have one sink pad and one source pad. It uses + the values of the pixels received on its sink pad to look up + entries in internal tables and output them on its source pad. + The lookup processing can be performed on all components + separately or combine them for multi-dimensional table + lookups. + + + + MEDIA_ENT_F_PROC_VIDEO_SCALER + Video scaler. An entity capable of video scaling must have + at least one sink pad and one source pad, and scale the + video frame(s) received on its sink pad(s) to a different + resolution output on its source pad(s). The range of + supported scaling ratios is entity-specific and can differ + between the horizontal and vertical directions (in particular + scaling can be supported in one direction only). Binning and + skipping are considered as scaling. + + diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index df59edee25d1..3136686c4bd0 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -94,6 +94,15 @@ struct media_device_info { #define MEDIA_ENT_F_AUDIO_PLAYBACK (MEDIA_ENT_F_BASE + 0x03002) #define MEDIA_ENT_F_AUDIO_MIXER (MEDIA_ENT_F_BASE + 0x03003) +/* + * Processing entities + */ +#define MEDIA_ENT_F_PROC_VIDEO_COMPOSER (MEDIA_ENT_F_BASE + 0x4001) +#define MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER (MEDIA_ENT_F_BASE + 0x4002) +#define MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV (MEDIA_ENT_F_BASE + 0x4003) +#define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004) +#define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005) + /* * Connectors */ -- cgit v1.3-14-g43fede From eaa0b96bbb6586a95e66d3dedd974313d7b0d94f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 1 Mar 2016 21:12:27 -0300 Subject: [media] media: Add video statistics computation functions The video statistics function describes entities such as video histogram engines or 3A statistics engines. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/media-types.xml | 9 +++++++++ include/uapi/linux/media.h | 1 + 2 files changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml index 60fe841f8846..95aa1f9c836a 100644 --- a/Documentation/DocBook/media/v4l/media-types.xml +++ b/Documentation/DocBook/media/v4l/media-types.xml @@ -176,6 +176,15 @@ skipping are considered as scaling. + + MEDIA_ENT_F_PROC_VIDEO_STATISTICS + Video statistics computation (histogram, 3A, ...). An entity + capable of statistics computation must have one sink pad and + one source pad. It computes statistics over the frames + received on its sink pad and outputs the statistics data on + its source pad. + + diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3136686c4bd0..7acf0f634f70 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -102,6 +102,7 @@ struct media_device_info { #define MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV (MEDIA_ENT_F_BASE + 0x4003) #define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004) #define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005) +#define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006) /* * Connectors -- cgit v1.3-14-g43fede From 69b76795e1e262349dc5a8af29eeac25038923ae Mon Sep 17 00:00:00 2001 From: Jiancheng Xue Date: Wed, 15 Jun 2016 10:19:06 +0800 Subject: ARM: dt-bindings: add device tree bindings for Hi3519 sysctrl Add device tree bindings for Hi3519 system controller. Signed-off-by: Jiancheng Xue Acked-by: Rob Herring Signed-off-by: Wei Xu --- .../devicetree/bindings/arm/hisilicon/hi3519-sysctrl.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/hi3519-sysctrl.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hi3519-sysctrl.txt b/Documentation/devicetree/bindings/arm/hisilicon/hi3519-sysctrl.txt new file mode 100644 index 000000000000..115c5be0bd0b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/hisilicon/hi3519-sysctrl.txt @@ -0,0 +1,14 @@ +* Hisilicon Hi3519 System Controller Block + +This bindings use the following binding: +Documentation/devicetree/bindings/mfd/syscon.txt + +Required properties: +- compatible: "hisilicon,hi3519-sysctrl". +- reg: the register region of this block + +Examples: +sysctrl: system-controller@12010000 { + compatible = "hisilicon,hi3519-sysctrl", "syscon"; + reg = <0x12010000 0x1000>; +}; -- cgit v1.3-14-g43fede From 4aff217e77a88f6d8c21156e02dfcd32e65171a3 Mon Sep 17 00:00:00 2001 From: Chris Lapa Date: Fri, 24 Jun 2016 12:26:06 +1000 Subject: max8903: adds documentation for device tree bindings. Signed-off-by: Chris Lapa Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sebastian Reichel --- .../devicetree/bindings/power/max8903-charger.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/max8903-charger.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/power/max8903-charger.txt b/Documentation/devicetree/bindings/power/max8903-charger.txt new file mode 100644 index 000000000000..f0f4e12b076e --- /dev/null +++ b/Documentation/devicetree/bindings/power/max8903-charger.txt @@ -0,0 +1,25 @@ +Maxim Semiconductor MAX8903 Battery Charger bindings + +Required properties: +- compatible: "maxim,max8903" for MAX8903 Battery Charger +- dok-gpios: Valid DC power has been detected (active low, input), optional if uok-gpios is provided +- uok-gpios: Valid USB power has been detected (active low, input), optional if dok-gpios is provided + +Optional properties: +- cen-gpios: Charge enable pin (active low, output) +- chg-gpios: Charger status pin (active low, input) +- flt-gpios: Fault pin (active low, output) +- dcm-gpios: Current limit mode setting (DC=1 or USB=0, output) +- usus-gpios: USB suspend pin (active high, output) + + +Example: + + max8903-charger { + compatible = "maxim,max8903"; + dok-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; + flt-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; + chg-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; + cen-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; + status = "okay"; + }; -- cgit v1.3-14-g43fede From 0fb7620fba7feb977a5138f8d7f6b42514f81ea9 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 29 Jun 2016 04:33:33 +0900 Subject: spi: Fix typo in devicetree/bindings/spi This patch fix spelling typos found in Documentation/devicetree/bingings/spi. Signed-off-by: Masanari Iida Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-davinci.txt | 2 +- Documentation/devicetree/bindings/spi/ti_qspi.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt index d1e914adcf6e..f5916c92fe91 100644 --- a/Documentation/devicetree/bindings/spi/spi-davinci.txt +++ b/Documentation/devicetree/bindings/spi/spi-davinci.txt @@ -21,7 +21,7 @@ Required properties: IP to the interrupt controller within the SoC. Possible values are 0 and 1. Manual says one of the two possible interrupt lines can be tied to the interrupt controller. Set this - based on a specifc SoC configuration. + based on a specific SoC configuration. - interrupts: interrupt number mapped to CPU. - clocks: spi clk phandle diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt b/Documentation/devicetree/bindings/spi/ti_qspi.txt index 50b14f6b53a3..e65fde4a7388 100644 --- a/Documentation/devicetree/bindings/spi/ti_qspi.txt +++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt @@ -20,7 +20,7 @@ Optional properties: chipselect register and offset of that register. NOTE: TI QSPI controller requires different pinmux and IODelay -paramaters for Mode-0 and Mode-3 operations, which needs to be set up by +parameters for Mode-0 and Mode-3 operations, which needs to be set up by the bootloader (U-Boot). Default configuration only supports Mode-0 operation. Hence, "spi-cpol" and "spi-cpha" DT properties cannot be specified in the slave nodes of TI QSPI controller without appropriate -- cgit v1.3-14-g43fede From 141fd28cee8b0a4636e8f9c9e10d7d22bed3b108 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 29 Jun 2016 05:10:57 +0900 Subject: Doc: block: Fix a typo in queue-sysfs.txt This patch fix a spelling typo found in queue-sysfs.txt. Signed-off-by: Masanari Iida Signed-off-by: Jens Axboe --- Documentation/block/queue-sysfs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index dce25d848d92..d515d58962b9 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt @@ -53,7 +53,7 @@ disk. logical_block_size (RO) ----------------------- -This is the logcal block size of the device, in bytes. +This is the logical block size of the device, in bytes. max_hw_sectors_kb (RO) ---------------------- -- cgit v1.3-14-g43fede From 1ae88fd54c3ac31f68f91e37f719be7e2dbcc810 Mon Sep 17 00:00:00 2001 From: Suraj Jitindar Singh Date: Wed, 29 Jun 2016 13:38:37 +1000 Subject: devicetree/bindings: Add binding for operator panel on FSP machines Add a binding to Documentation/devicetree/bindings/powerpc/opal (oppanel-opal.txt) for the operator panel which is present on IBM Power Systems machines with FSPs. Signed-off-by: Suraj Jitindar Singh Acked-by: Rob Herring Acked-by: Stewart Smith Signed-off-by: Michael Ellerman --- .../devicetree/bindings/powerpc/opal/oppanel-opal.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Documentation/devicetree/bindings/powerpc/opal/oppanel-opal.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/powerpc/opal/oppanel-opal.txt b/Documentation/devicetree/bindings/powerpc/opal/oppanel-opal.txt new file mode 100644 index 000000000000..dffb79108b61 --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/opal/oppanel-opal.txt @@ -0,0 +1,14 @@ +IBM OPAL Operator Panel Binding +------------------------------- + +Required properties: +- compatible : Should be "ibm,opal-oppanel". +- #lines : Number of lines on the operator panel e.g. <0x2>. +- #length : Number of characters per line of the operator panel e.g. <0x10>. + +Example: + oppanel { + compatible = "ibm,opal-oppanel"; + #lines = <0x2>; + #length = <0x10>; + }; -- cgit v1.3-14-g43fede From af3f1de4e713062252b58c1cd481592d9e5211bf Mon Sep 17 00:00:00 2001 From: Yendapally Reddy Dhananjaya Reddy Date: Thu, 23 Jun 2016 13:35:06 -0400 Subject: pinctrl: Broadcom NSP pinctrl device tree bindings Device tree binding documentation for Broadcom NSP IOMUX driver Signed-off-by: Yendapally Reddy Dhananjaya Reddy Signed-off-by: Linus Walleij --- .../bindings/pinctrl/brcm,nsp-pinmux.txt | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt new file mode 100644 index 000000000000..603564e5fe6f --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,nsp-pinmux.txt @@ -0,0 +1,79 @@ +Broadcom NSP (Northstar plus) IOMUX Controller + +The NSP IOMUX controller supports group based mux configuration. In +addition, certain pins can be muxed to GPIO function individually. + +Required properties: +- compatible: + Must be "brcm,nsp-pinmux" + +- reg: + Should contain the register physical address and length for each of + GPIO_CONTROL0, GP_AUX_SEL and IPROC_CONFIG IOMUX registers + +Properties in subnodes: +- function: + The mux function to select + +- groups: + The list of groups to select with a given function + +For more details, refer to +Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt + +For example: + + pinmux: pinmux@1803f1c0 { + compatible = "brcm,nsp-pinmux"; + reg = <0x1803f1c0 0x04>, + <0x18030028 0x04>, + <0x1803f408 0x04>; + + pinctrl-names = "default"; + pinctrl-0 = <&pwm &gpio_b &nand_sel>; + + pwm: pwm { + function = "pwm"; + groups = "pwm0_grp", "pwm1_grp"; + }; + + gpio_b: gpio_b { + function = "gpio_b"; + groups = "gpio_b_0_grp", "gpio_b_1_grp"; + }; + + nand_sel: nand_sel { + function = "nand"; + groups = "nand_grp"; + }; + }; + +List of supported functions and groups in Northstar Plus: + +"spi": "spi_grp" + +"i2c": "i2c_grp" + +"mdio": "mdio_grp" + +"pwm": "pwm0_grp", "pwm1_grp", "pwm2_grp", "pwm3_grp" + +"gpio_b": "gpio_b_0_grp", "gpio_b_1_grp", "gpio_b_2_grp", "gpio_b_3_grp" + +"uart1": "uart1_grp" + +"uart2": "uart2_grp" + +"synce": "synce_grp" + +"sata_led_grps": "sata0_led_grp", "sata1_led_grp" + +"xtal_out": "xtal_out_grp" + +"sdio": "sdio_pwr_grp", "sdio_1p8v_grp" + +"switch_led": "switch_p05_led0_grp", "switch_p05_led1_grp" + +"nand": "nand_grp" + +"emmc": "emmc_grp" -- cgit v1.3-14-g43fede From cdd5b3485cd59cb7d9004874d2ac99522da5e624 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 17 Jun 2016 12:15:35 +0200 Subject: dt-bindings: pinctrl: Add MDM9615 TLMM bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Neil Armstrong Acked-by: Rob Herring Acked-by: Björn Andersson Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,mdm9615-pinctrl.txt | 152 +++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,mdm9615-pinctrl.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,mdm9615-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,mdm9615-pinctrl.txt new file mode 100644 index 000000000000..1b52f01ddcb7 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,mdm9615-pinctrl.txt @@ -0,0 +1,152 @@ +Qualcomm MDM9615 TLMM block + +This binding describes the Top Level Mode Multiplexer block found in the +MDM9615 platform. + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,mdm9615-pinctrl" + +- reg: + Usage: required + Value type: + Definition: the base address and size of the TLMM register space. + +- interrupts: + Usage: required + Value type: + Definition: should specify the TLMM summary IRQ. + +- interrupt-controller: + Usage: required + Value type: + Definition: identifies this node as an interrupt controller + +- #interrupt-cells: + Usage: required + Value type: + Definition: must be 2. Specifying the pin number and flags, as defined + in + +- gpio-controller: + Usage: required + Value type: + Definition: identifies this node as a gpio controller + +- #gpio-cells: + Usage: required + Value type: + Definition: must be 2. Specifying the pin number and flags, as defined + in + +Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for +a general description of GPIO and interrupt bindings. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +The pin configuration nodes act as a container for an arbitrary number of +subnodes. Each of these subnodes represents some desired configuration for a +pin, a group, or a list of pins or groups. This configuration can include the +mux function to select on those pin(s)/group(s), and various pin configuration +parameters, such as pull-up, drive strength, etc. + + +PIN CONFIGURATION NODES: + +The name of each subnode is not important; all subnodes should be enumerated +and processed purely based on their content. + +Each subnode only affects those parameters that are explicitly listed. In +other words, a subnode that lists a mux function but no pin configuration +parameters implies no information about any pin configuration parameters. +Similarly, a pin subnode that describes a pullup parameter implies no +information about e.g. the mux function. + + +The following generic properties as defined in pinctrl-bindings.txt are valid +to specify in a pin configuration subnode: + +- pins: + Usage: required + Value type: + Definition: List of gpio pins affected by the properties specified in + this subnode. Valid pins are: + gpio0-gpio87 + +- function: + Usage: required + Value type: + Definition: Specify the alternative function to be configured for the + specified pins. + Valid values are: + gpio, gsbi2_i2c, gsbi3, gsbi4, gsbi5_i2c, gsbi5_uart, + sdc2, ebi2_lcdc, ps_hold, prim_audio, sec_audio, + cdc_mclk + +- bias-disable: + Usage: optional + Value type: + Definition: The specified pins should be configued as no pull. + +- bias-pull-down: + Usage: optional + Value type: + Definition: The specified pins should be configued as pull down. + +- bias-pull-up: + Usage: optional + Value type: + Definition: The specified pins should be configued as pull up. + +- output-high: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + high. + +- output-low: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + low. + +- drive-strength: + Usage: optional + Value type: + Definition: Selects the drive strength for the specified pins, in mA. + Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16 + +Example: + + msmgpio: pinctrl@800000 { + compatible = "qcom,mdm9615-pinctrl"; + reg = <0x800000 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 16 0x4>; + + gsbi8_uart: gsbi8-uart { + mux { + pins = "gpio34", "gpio35"; + function = "gsbi8"; + }; + + tx { + pins = "gpio34"; + drive-strength = <4>; + bias-disable; + }; + + rx { + pins = "gpio35"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; -- cgit v1.3-14-g43fede From a1c166aca3d555c6171e9027b81244d4c09099fa Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 25 Jun 2016 22:21:32 -0700 Subject: pinctrl: qcom: msm8974: Add hsic_ctl pinmux The msm8974 pinctrl variant has a couple USB HSIC "glue" registers that let us mux between the pinctrl register settings or the HSIC core settings for the HSIC pins (gpio 144 and gpio 145). Support this method of operation by adding hsic_data and hsic_strobe pins that can select between hsic_ctl and gpio functions. This allows us to toggle the hsic pin configuration over to the HSIC core at runtime. Cc: Bjorn Andersson Signed-off-by: Stephen Boyd Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,msm8974-pinctrl.txt | 5 ++- drivers/pinctrl/qcom/pinctrl-msm8x74.c | 43 +++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt index e4d6a9d20f7d..453bd7c76d6b 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt @@ -49,6 +49,9 @@ Valid values for pins are: sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data Supports bias and drive-strength + hsic_data, hsic_strobe + Supports only mux + Valid values for function are: cci_i2c0, cci_i2c1, uim1, uim2, uim_batt_alarm, blsp_uim1, blsp_uart1, blsp_i2c1, blsp_spi1, @@ -70,7 +73,7 @@ Valid values for function are: cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc, hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk, gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s, - ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio + ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, hsic_ctl, gpio (Note that this is not yet the complete list of functions) diff --git a/drivers/pinctrl/qcom/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c index 46fe6ad5f97e..9eb63d3403d4 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8x74.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c @@ -172,6 +172,8 @@ static const struct pinctrl_pin_desc msm8x74_pins[] = { PINCTRL_PIN(149, "SDC2_CLK"), PINCTRL_PIN(150, "SDC2_CMD"), PINCTRL_PIN(151, "SDC2_DATA"), + PINCTRL_PIN(152, "HSIC_STROBE"), + PINCTRL_PIN(153, "HSIC_DATA"), }; #define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin } @@ -328,6 +330,8 @@ static const unsigned int sdc1_data_pins[] = { 148 }; static const unsigned int sdc2_clk_pins[] = { 149 }; static const unsigned int sdc2_cmd_pins[] = { 150 }; static const unsigned int sdc2_data_pins[] = { 151 }; +static const unsigned int hsic_strobe_pins[] = { 152 }; +static const unsigned int hsic_data_pins[] = { 153 }; #define FUNCTION(fname) \ [MSM_MUX_##fname] = { \ @@ -399,6 +403,37 @@ static const unsigned int sdc2_data_pins[] = { 151 }; .intr_detection_width = -1, \ } +#define HSIC_PINGROUP(pg_name, ctl) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .funcs = (int[]){ \ + MSM_MUX_gpio, \ + MSM_MUX_hsic_ctl, \ + }, \ + .nfuncs = 2, \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = 25, \ + .pull_bit = -1, \ + .drv_bit = -1, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_target_kpss_val = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + /* * TODO: Add the rest of the possible functions and fill out * the pingroup table below. @@ -509,6 +544,7 @@ enum msm8x74_functions { MSM_MUX_fm, MSM_MUX_wlan, MSM_MUX_slimbus, + MSM_MUX_hsic_ctl, MSM_MUX_NA, }; @@ -534,7 +570,8 @@ static const char * const gpio_groups[] = { "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128", "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134", "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", - "gpio141", "gpio142", "gpio143", "gpio144", "gpio145" + "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "hsic_data", + "hsic_strobe", }; static const char * const blsp_uart1_groups[] = { @@ -754,6 +791,7 @@ static const char * const wlan_groups[] = { }; static const char * const slimbus_groups[] = { "gpio70", "gpio71" }; +static const char * const hsic_ctl_groups[] = { "hsic_strobe", "hsic_data" }; static const struct msm_function msm8x74_functions[] = { FUNCTION(gpio), @@ -861,6 +899,7 @@ static const struct msm_function msm8x74_functions[] = { FUNCTION(fm), FUNCTION(wlan), FUNCTION(slimbus), + FUNCTION(hsic_ctl), }; static const struct msm_pingroup msm8x74_groups[] = { @@ -1016,6 +1055,8 @@ static const struct msm_pingroup msm8x74_groups[] = { SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6), SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3), SDC_PINGROUP(sdc2_data, 0x2048, 9, 0), + HSIC_PINGROUP(hsic_strobe, 0x2050), + HSIC_PINGROUP(hsic_data, 0x2054), }; #define NUM_GPIO_PINGROUPS 146 -- cgit v1.3-14-g43fede From 602553073892c18f723f8aa090153a23b1312a16 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 10 Jun 2016 12:39:57 -0700 Subject: backlight: lp855x: Add enable regulator The LP8556 datasheet describes an EN/VDDIO input, which serves "both as a chip enable and as a power supply reference for PWM, SDA, and SCL inputs." The LP8556 that I'm testing doesn't respond properly if I try to talk I2C to it too quickly after enabling VDDIO, and the LP8555 datasheet mentions a t_RESPONSE delay of up to 1 millisecond. Support this EN/VDDIO by adding a regulator property to the binding; enabling this regulator at probe time; and sleeping for 1 to 2ms, if the EN/VDDIO regulator was provided. Signed-off-by: Brian Norris Acked-by: Rob Herring Acked-by: Milo Kim Reviewed-by: Stephen Barber Signed-off-by: Lee Jones --- .../devicetree/bindings/leds/backlight/lp855x.txt | 2 ++ drivers/video/backlight/lp855x_bl.c | 29 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/leds/backlight/lp855x.txt b/Documentation/devicetree/bindings/leds/backlight/lp855x.txt index 0a3ecbc3a1b9..88f56641fc28 100644 --- a/Documentation/devicetree/bindings/leds/backlight/lp855x.txt +++ b/Documentation/devicetree/bindings/leds/backlight/lp855x.txt @@ -13,6 +13,7 @@ Optional properties: - rom-addr: Register address of ROM area to be updated (u8) - rom-val: Register value to be updated (u8) - power-supply: Regulator which controls the 3V rail + - enable-supply: Regulator which controls the EN/VDDIO input Example: @@ -57,6 +58,7 @@ Example: backlight@2c { compatible = "ti,lp8557"; reg = <0x2c>; + enable-supply = <&backlight_vddio>; power-supply = <&backlight_vdd>; dev-ctrl = /bits/ 8 <0x41>; diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index e5b14f52628f..939f057836e1 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ struct lp855x { struct lp855x_platform_data *pdata; struct pwm_device *pwm; struct regulator *supply; /* regulator for VDD input */ + struct regulator *enable; /* regulator for EN/VDDIO input */ }; static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data) @@ -433,6 +435,19 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) lp->supply = NULL; } + lp->enable = devm_regulator_get_optional(lp->dev, "enable"); + if (IS_ERR(lp->enable)) { + ret = PTR_ERR(lp->enable); + if (ret == -ENODEV) { + lp->enable = NULL; + } else { + if (ret != -EPROBE_DEFER) + dev_err(lp->dev, "error getting enable regulator: %d\n", + ret); + return ret; + } + } + if (lp->supply) { ret = regulator_enable(lp->supply); if (ret < 0) { @@ -441,6 +456,20 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) } } + if (lp->enable) { + ret = regulator_enable(lp->enable); + if (ret < 0) { + dev_err(lp->dev, "failed to enable vddio: %d\n", ret); + return ret; + } + + /* + * LP8555 datasheet says t_RESPONSE (time between VDDIO and + * I2C) is 1ms. + */ + usleep_range(1000, 2000); + } + i2c_set_clientdata(cl, lp); ret = lp855x_configure(lp); -- cgit v1.3-14-g43fede From a99ab50dbbb1f982d076d19e0a9959fe2efa3126 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 28 Jun 2016 22:53:19 -0700 Subject: mfd: rn5t618: Add Ricoh RN5T567 PMIC support The Ricoh RN5T567 is from the same family as the Ricoh RN5T618 is, the differences are: + DCDC4 + Slightly different output voltage/currents + 32kHz Output - ADC/Charger capabilities Signed-off-by: Stefan Agner Reviewed-by: Marcel Ziswiler Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/rn5t618.txt | 19 +++++++++-------- drivers/mfd/Kconfig | 7 ++++--- drivers/mfd/rn5t618.c | 25 ++++++++++++++++------- include/linux/mfd/rn5t618.h | 12 +++++++++++ 4 files changed, 45 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/rn5t618.txt b/Documentation/devicetree/bindings/mfd/rn5t618.txt index 937785a3eddc..9e6770b105c9 100644 --- a/Documentation/devicetree/bindings/mfd/rn5t618.txt +++ b/Documentation/devicetree/bindings/mfd/rn5t618.txt @@ -1,18 +1,21 @@ -* Ricoh RN5T618 PMIC +* Ricoh RN5T567/RN5T618 PMIC -Ricoh RN5T618 is a power management IC which integrates 3 step-down -DCDC converters, 7 low-dropout regulators, a Li-ion battery charger, -fuel gauge, ADC, GPIOs and a watchdog timer. It can be controlled -through a I2C interface. +Ricoh RN5T567/RN5T618 is a power management IC family which integrates +3 to 4 step-down DCDC converters, 7 low-dropout regulators, GPIOs and +a watchdog timer. The RN5T618 provides additionally a Li-ion battery +charger, fuel gauge and an ADC. It can be controlled through an I2C +interface. Required properties: - - compatible: should be "ricoh,rn5t618" + - compatible: must be one of + "ricoh,rn5t567" + "ricoh,rn5t618" - reg: the I2C slave address of the device Sub-nodes: - regulators: the node is required if the regulator functionality is - needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, LDO1, - LDO2, LDO3, LDO4, LDO5, LDORTC1 and LDORTC2. + needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4 + (RN5T567), LDO1, LDO2, LDO3, LDO4, LDO5, LDORTC1 and LDORTC2. The common bindings for each individual regulator can be found in: Documentation/devicetree/bindings/regulator/regulator.txt diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 1bcf601de5bc..ff031a7735a5 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -852,13 +852,14 @@ config MFD_RK808 including interrupts, RTC, LDO & DCDC regulators, and onkey. config MFD_RN5T618 - tristate "Ricoh RN5T5618 PMIC" + tristate "Ricoh RN5T567/618 PMIC" depends on I2C + depends on OF select MFD_CORE select REGMAP_I2C help - Say yes here to add support for the Ricoh RN5T618 PMIC. This - driver provides common support for accessing the device, + Say yes here to add support for the Ricoh RN5T567 or R5T618 PMIC. + This driver provides common support for accessing the device, additional drivers must be enabled in order to use the functionality of the device. diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 0ad51d792feb..c86160d3a773 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -2,6 +2,7 @@ * MFD core driver for Ricoh RN5T618 PMIC * * Copyright (C) 2014 Beniamino Galvani + * Copyright (C) 2016 Toradex AG * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,6 +16,7 @@ #include #include #include +#include #include static const struct mfd_cell rn5t618_cells[] = { @@ -59,17 +61,32 @@ static void rn5t618_power_off(void) RN5T618_SLPCNT_SWPWROFF, RN5T618_SLPCNT_SWPWROFF); } +static const struct of_device_id rn5t618_of_match[] = { + { .compatible = "ricoh,rn5t567", .data = (void *)RN5T567 }, + { .compatible = "ricoh,rn5t618", .data = (void *)RN5T618 }, + { } +}; +MODULE_DEVICE_TABLE(of, rn5t618_of_match); + static int rn5t618_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + const struct of_device_id *of_id; struct rn5t618 *priv; int ret; + of_id = of_match_device(rn5t618_of_match, &i2c->dev); + if (!of_id) { + dev_err(&i2c->dev, "Failed to find matching DT ID\n"); + return -EINVAL; + } + priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; i2c_set_clientdata(i2c, priv); + priv->variant = (long)of_id->data; priv->regmap = devm_regmap_init_i2c(i2c, &rn5t618_regmap_config); if (IS_ERR(priv->regmap)) { @@ -105,12 +122,6 @@ static int rn5t618_i2c_remove(struct i2c_client *i2c) return 0; } -static const struct of_device_id rn5t618_of_match[] = { - { .compatible = "ricoh,rn5t618" }, - { } -}; -MODULE_DEVICE_TABLE(of, rn5t618_of_match); - static const struct i2c_device_id rn5t618_i2c_id[] = { { } }; @@ -129,5 +140,5 @@ static struct i2c_driver rn5t618_i2c_driver = { module_i2c_driver(rn5t618_i2c_driver); MODULE_AUTHOR("Beniamino Galvani "); -MODULE_DESCRIPTION("Ricoh RN5T618 MFD driver"); +MODULE_DESCRIPTION("Ricoh RN5T567/618 MFD driver"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/rn5t618.h b/include/linux/mfd/rn5t618.h index c72d5344f3b3..54179c2577ae 100644 --- a/include/linux/mfd/rn5t618.h +++ b/include/linux/mfd/rn5t618.h @@ -20,6 +20,7 @@ #define RN5T618_OTPVER 0x01 #define RN5T618_IODAC 0x02 #define RN5T618_VINDAC 0x03 +#define RN5T618_OUT32KEN 0x05 #define RN5T618_CPUCNT 0x06 #define RN5T618_PSWR 0x07 #define RN5T618_PONHIS 0x09 @@ -38,6 +39,7 @@ #define RN5T618_DC1_SLOT 0x16 #define RN5T618_DC2_SLOT 0x17 #define RN5T618_DC3_SLOT 0x18 +#define RN5T618_DC4_SLOT 0x19 #define RN5T618_LDO1_SLOT 0x1b #define RN5T618_LDO2_SLOT 0x1c #define RN5T618_LDO3_SLOT 0x1d @@ -54,12 +56,16 @@ #define RN5T618_DC2CTL2 0x2f #define RN5T618_DC3CTL 0x30 #define RN5T618_DC3CTL2 0x31 +#define RN5T618_DC4CTL 0x32 +#define RN5T618_DC4CTL2 0x33 #define RN5T618_DC1DAC 0x36 #define RN5T618_DC2DAC 0x37 #define RN5T618_DC3DAC 0x38 +#define RN5T618_DC4DAC 0x39 #define RN5T618_DC1DAC_SLP 0x3b #define RN5T618_DC2DAC_SLP 0x3c #define RN5T618_DC3DAC_SLP 0x3d +#define RN5T618_DC4DAC_SLP 0x3e #define RN5T618_DCIREN 0x40 #define RN5T618_DCIRQ 0x41 #define RN5T618_DCIRMON 0x42 @@ -221,8 +227,14 @@ enum { RN5T618_REG_NUM, }; +enum { + RN5T567 = 0, + RN5T618, +}; + struct rn5t618 { struct regmap *regmap; + long variant; }; #endif /* __LINUX_MFD_RN5T618_H */ -- cgit v1.3-14-g43fede From 0a58da1e2f25f213fb72d7d6a18dff9562621215 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 20 Jun 2016 17:07:18 +0300 Subject: mfd: twl6040: Handle mclk used for HPPLL and optional internal clock source On some boards, like omap5-uevm the MCLK is gated by default and in order to be able to use the High performance modes of twl6040 it need to be enabled by SW. Add support for handling the MCLK source clock via CCF. At the same time lower the print priority of the notification that the 32K clock is not provided and it is not going to be handled by the driver. Signed-off-by: Peter Ujfalusi Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/twl6040.txt | 4 +-- drivers/mfd/twl6040.c | 41 ++++++++++++++++------- include/linux/mfd/twl6040.h | 5 +-- 3 files changed, 34 insertions(+), 16 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/mfd/twl6040.txt b/Documentation/devicetree/bindings/mfd/twl6040.txt index a41157b5d930..e6afdfa3543d 100644 --- a/Documentation/devicetree/bindings/mfd/twl6040.txt +++ b/Documentation/devicetree/bindings/mfd/twl6040.txt @@ -19,8 +19,8 @@ Required properties: Optional properties, nodes: - enable-active-high: To power on the twl6040 during boot. -- clocks: phandle to the clk32k clock provider -- clock-names: Must be "clk32k" +- clocks: phandle to the clk32k and/or to mclk clock provider +- clock-names: Must be "clk32k" for the 32K clock and "mclk" for the MCLK. Vibra functionality Required properties: diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index 852d5874aabb..ab328ec49353 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c @@ -323,8 +323,7 @@ int twl6040_power(struct twl6040 *twl6040, int on) /* Default PLL configuration after power up */ twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; - twl6040->sysclk = 19200000; - twl6040->mclk = 32768; + twl6040->sysclk_rate = 19200000; } else { /* already powered-down */ if (!twl6040->power_count) { @@ -352,8 +351,12 @@ int twl6040_power(struct twl6040 *twl6040, int on) regcache_cache_only(twl6040->regmap, true); regcache_mark_dirty(twl6040->regmap); - twl6040->sysclk = 0; - twl6040->mclk = 0; + twl6040->sysclk_rate = 0; + + if (twl6040->pll == TWL6040_SYSCLK_SEL_HPPLL) { + clk_disable_unprepare(twl6040->mclk); + twl6040->mclk_rate = 0; + } clk_disable_unprepare(twl6040->clk32k); } @@ -377,15 +380,15 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, /* Force full reconfiguration when switching between PLL */ if (pll_id != twl6040->pll) { - twl6040->sysclk = 0; - twl6040->mclk = 0; + twl6040->sysclk_rate = 0; + twl6040->mclk_rate = 0; } switch (pll_id) { case TWL6040_SYSCLK_SEL_LPPLL: /* low-power PLL divider */ /* Change the sysclk configuration only if it has been canged */ - if (twl6040->sysclk != freq_out) { + if (twl6040->sysclk_rate != freq_out) { switch (freq_out) { case 17640000: lppllctl |= TWL6040_LPLLFIN; @@ -427,6 +430,8 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, ret = -EINVAL; goto pll_out; } + + clk_disable_unprepare(twl6040->mclk); break; case TWL6040_SYSCLK_SEL_HPPLL: /* high-performance PLL can provide only 19.2 MHz */ @@ -437,7 +442,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, goto pll_out; } - if (twl6040->mclk != freq_in) { + if (twl6040->mclk_rate != freq_in) { hppllctl &= ~TWL6040_MCLK_MSK; switch (freq_in) { @@ -468,6 +473,9 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, goto pll_out; } + /* When switching to HPPLL, enable the mclk first */ + if (pll_id != twl6040->pll) + clk_prepare_enable(twl6040->mclk); /* * enable clock slicer to ensure input waveform is * square @@ -483,6 +491,8 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, lppllctl &= ~TWL6040_LPLLENA; twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); + + twl6040->mclk_rate = freq_in; } break; default: @@ -491,8 +501,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, goto pll_out; } - twl6040->sysclk = freq_out; - twl6040->mclk = freq_in; + twl6040->sysclk_rate = freq_out; twl6040->pll = pll_id; pll_out: @@ -512,7 +521,7 @@ EXPORT_SYMBOL(twl6040_get_pll); unsigned int twl6040_get_sysclk(struct twl6040 *twl6040) { - return twl6040->sysclk; + return twl6040->sysclk_rate; } EXPORT_SYMBOL(twl6040_get_sysclk); @@ -655,10 +664,18 @@ static int twl6040_probe(struct i2c_client *client, if (IS_ERR(twl6040->clk32k)) { if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER) return -EPROBE_DEFER; - dev_info(&client->dev, "clk32k is not handled\n"); + dev_dbg(&client->dev, "clk32k is not handled\n"); twl6040->clk32k = NULL; } + twl6040->mclk = devm_clk_get(&client->dev, "mclk"); + if (IS_ERR(twl6040->mclk)) { + if (PTR_ERR(twl6040->mclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_dbg(&client->dev, "mclk is not handled\n"); + twl6040->mclk = NULL; + } + twl6040->supplies[0].supply = "vio"; twl6040->supplies[1].supply = "v2v1"; ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 8e95cd87cd74..36795a1be479 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -226,6 +226,7 @@ struct twl6040 { struct regmap_irq_chip_data *irq_data; struct regulator_bulk_data supplies[2]; /* supplies for vio, v2v1 */ struct clk *clk32k; + struct clk *mclk; struct mutex mutex; struct mutex irq_mutex; struct mfd_cell cells[TWL6040_CELLS]; @@ -237,8 +238,8 @@ struct twl6040 { /* PLL configuration */ int pll; - unsigned int sysclk; - unsigned int mclk; + unsigned int sysclk_rate; + unsigned int mclk_rate; unsigned int irq; unsigned int irq_ready; -- cgit v1.3-14-g43fede From e454b359b7a0a6f59e3d83394e6d4e598554cb33 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 28 Jun 2016 16:10:30 +0200 Subject: devicetree: bindings: Renesas APMU and SMP Enable method Add DT binding documentation for the APMU hardware and add "renesas,apmu" to the list of enable methods for the ARM cpus. Signed-off-by: Magnus Damm Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Cc: devicetree@vger.kernel.org Signed-off-by: Simon Horman --- Documentation/devicetree/bindings/arm/cpus.txt | 1 + .../devicetree/bindings/power/renesas,apmu.txt | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/renesas,apmu.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 3f0cbbb8395f..fa7520eb6387 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -204,6 +204,7 @@ nodes to be present and contain the properties described below. "qcom,gcc-msm8660" "qcom,kpss-acc-v1" "qcom,kpss-acc-v2" + "renesas,apmu" "rockchip,rk3036-smp" "rockchip,rk3066-smp" "ste,dbx500-smp" diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.txt b/Documentation/devicetree/bindings/power/renesas,apmu.txt new file mode 100644 index 000000000000..84404c9edff7 --- /dev/null +++ b/Documentation/devicetree/bindings/power/renesas,apmu.txt @@ -0,0 +1,31 @@ +DT bindings for the Renesas Advanced Power Management Unit + +Renesas R-Car line of SoCs utilize one or more APMU hardware units +for CPU core power domain control including SMP boot and CPU Hotplug. + +Required properties: + +- compatible: Should be "renesas,-apmu", "renesas,apmu" as fallback. + Examples with soctypes are: + - "renesas,r8a7790-apmu" (R-Car H2) + - "renesas,r8a7791-apmu" (R-Car M2-W) + - "renesas,r8a7792-apmu" (R-Car V2H) + - "renesas,r8a7793-apmu" (R-Car M2-N) + - "renesas,r8a7794-apmu" (R-Car E2) + +- reg: Base address and length of the I/O registers used by the APMU. + +- cpus: This node contains a list of CPU cores, which should match the order + of CPU cores used by the WUPCR and PSTR registers in the Advanced Power + Management Unit section of the device's datasheet. + + +Example: + +This shows the r8a7791 APMU that can control CPU0 and CPU1. + + apmu@e6152000 { + compatible = "renesas,r8a7791-apmu", "renesas,apmu"; + reg = <0 0xe6152000 0 0x188>; + cpus = <&cpu0 &cpu1>; + }; -- cgit v1.3-14-g43fede From 7524c1cebc0a4e2ab186fcb5f87116f3d9018ee4 Mon Sep 17 00:00:00 2001 From: James Ban Date: Wed, 29 Jun 2016 16:49:32 +0900 Subject: regulator: da9211: add descriptions for da9212/da9214 This is a patch for adding description for da9212/da9214. Signed-off-by: James Ban Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/da9211.txt | 47 +++++++++++++++++++--- drivers/regulator/da9211-regulator.c | 13 ++++-- drivers/regulator/da9211-regulator.h | 3 +- include/linux/regulator/da9211.h | 5 ++- 4 files changed, 57 insertions(+), 11 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/da9211.txt b/Documentation/devicetree/bindings/regulator/da9211.txt index c620493e8dbe..0f2a6f8fcafd 100644 --- a/Documentation/devicetree/bindings/regulator/da9211.txt +++ b/Documentation/devicetree/bindings/regulator/da9211.txt @@ -1,7 +1,8 @@ -* Dialog Semiconductor DA9211/DA9213/DA9215 Voltage Regulator +* Dialog Semiconductor DA9211/DA9212/DA9213/DA9214/DA9215 Voltage Regulator Required properties: -- compatible: "dlg,da9211" or "dlg,da9213" or "dlg,da9215" +- compatible: "dlg,da9211" or "dlg,da9212" or "dlg,da9213" + or "dlg,da9214" or "dlg,da9215" - reg: I2C slave address, usually 0x68. - interrupts: the interrupt outputs of the controller - regulators: A node that houses a sub-node for each regulator within the @@ -21,6 +22,25 @@ Example 1) DA9211 reg = <0x68>; interrupts = <3 27>; + regulators { + BUCKA { + regulator-name = "VBUCKA"; + regulator-min-microvolt = < 300000>; + regulator-max-microvolt = <1570000>; + regulator-min-microamp = <2000000>; + regulator-max-microamp = <5000000>; + enable-gpios = <&gpio 27 0>; + }; + }; + }; + +Example 2) DA9212 + + pmic: da9212@68 { + compatible = "dlg,da9212"; + reg = <0x68>; + interrupts = <3 27>; + regulators { BUCKA { regulator-name = "VBUCKA"; @@ -41,12 +61,30 @@ Example 1) DA9211 }; }; -Example 2) DA9213 +Example 3) DA9213 pmic: da9213@68 { compatible = "dlg,da9213"; reg = <0x68>; interrupts = <3 27>; + regulators { + BUCKA { + regulator-name = "VBUCKA"; + regulator-min-microvolt = < 300000>; + regulator-max-microvolt = <1570000>; + regulator-min-microamp = <3000000>; + regulator-max-microamp = <6000000>; + enable-gpios = <&gpio 27 0>; + }; + }; + }; + +Example 4) DA9214 + pmic: da9214@68 { + compatible = "dlg,da9214"; + reg = <0x68>; + interrupts = <3 27>; + regulators { BUCKA { regulator-name = "VBUCKA"; @@ -67,8 +105,7 @@ Example 2) DA9213 }; }; - -Example 3) DA9215 +Example 5) DA9215 pmic: da9215@68 { compatible = "dlg,da9215"; reg = <0x68>; diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 236abf473db5..aa47280efd32 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -1,5 +1,6 @@ /* - * da9211-regulator.c - Regulator device driver for DA9211/DA9213/DA9215 + * da9211-regulator.c - Regulator device driver for DA9211/DA9212 + * /DA9213/DA9214/DA9215 * Copyright (C) 2015 Dialog Semiconductor Ltd. * * This library is free software; you can redistribute it and/or @@ -493,7 +494,9 @@ static int da9211_i2c_probe(struct i2c_client *i2c, static const struct i2c_device_id da9211_i2c_id[] = { {"da9211", DA9211}, + {"da9212", DA9212}, {"da9213", DA9213}, + {"da9214", DA9214}, {"da9215", DA9215}, {}, }; @@ -502,8 +505,10 @@ MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); #ifdef CONFIG_OF static const struct of_device_id da9211_dt_ids[] = { { .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] }, - { .compatible = "dlg,da9213", .data = &da9211_i2c_id[1] }, - { .compatible = "dlg,da9215", .data = &da9211_i2c_id[2] }, + { .compatible = "dlg,da9212", .data = &da9211_i2c_id[1] }, + { .compatible = "dlg,da9213", .data = &da9211_i2c_id[2] }, + { .compatible = "dlg,da9214", .data = &da9211_i2c_id[3] }, + { .compatible = "dlg,da9215", .data = &da9211_i2c_id[4] }, {}, }; MODULE_DEVICE_TABLE(of, da9211_dt_ids); @@ -521,5 +526,5 @@ static struct i2c_driver da9211_regulator_driver = { module_i2c_driver(da9211_regulator_driver); MODULE_AUTHOR("James Ban "); -MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213/DA9215"); +MODULE_DESCRIPTION("DA9211/DA9212/DA9213/DA9214/DA9215 regulator driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h index d6ad96fc64d3..b841bbf330cc 100644 --- a/drivers/regulator/da9211-regulator.h +++ b/drivers/regulator/da9211-regulator.h @@ -1,5 +1,6 @@ /* - * da9211-regulator.h - Regulator definitions for DA9211/DA9213/DA9215 + * da9211-regulator.h - Regulator definitions for DA9211/DA9212 + * /DA9213/DA9214/DA9215 * Copyright (C) 2015 Dialog Semiconductor Ltd. * * This program is free software; you can redistribute it and/or diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h index a43a5ca1167b..80cb40b7c88d 100644 --- a/include/linux/regulator/da9211.h +++ b/include/linux/regulator/da9211.h @@ -1,5 +1,6 @@ /* - * da9211.h - Regulator device driver for DA9211/DA9213/DA9215 + * da9211.h - Regulator device driver for DA9211/DA9212 + * /DA9213/DA9214/DA9215 * Copyright (C) 2015 Dialog Semiconductor Ltd. * * This program is free software; you can redistribute it and/or @@ -22,7 +23,9 @@ enum da9211_chip_id { DA9211, + DA9212, DA9213, + DA9214, DA9215, }; -- cgit v1.3-14-g43fede From d3986650647d5e5478b4c64c1b01098628577ac1 Mon Sep 17 00:00:00 2001 From: Garlic Tseng Date: Fri, 17 Jun 2016 15:43:55 +0800 Subject: ASoC: mediatek: add documents for mt2701 add mt2701-afe-pcm.txt and mt2701-cs42448.txt for mt2701 Signed-off-by: Garlic Tseng Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/mt2701-afe-pcm.txt | 150 +++++++++++++++++++++ .../devicetree/bindings/sound/mt2701-cs42448.txt | 43 ++++++ 2 files changed, 193 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt create mode 100644 Documentation/devicetree/bindings/sound/mt2701-cs42448.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt new file mode 100644 index 000000000000..3e623a724e55 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt @@ -0,0 +1,150 @@ +Mediatek AFE PCM controller for mt2701 + +Required properties: +- compatible = "mediatek,mt2701-audio"; +- reg: register location and size +- interrupts: Should contain AFE interrupt +- clock-names: should have these clock names: + "infra_sys_audio_clk", + "top_audio_mux1_sel", + "top_audio_mux2_sel", + "top_audio_mux1_div", + "top_audio_mux2_div", + "top_audio_48k_timing", + "top_audio_44k_timing", + "top_audpll_mux_sel", + "top_apll_sel", + "top_aud1_pll_98M", + "top_aud2_pll_90M", + "top_hadds2_pll_98M", + "top_hadds2_pll_294M", + "top_audpll", + "top_audpll_d4", + "top_audpll_d8", + "top_audpll_d16", + "top_audpll_d24", + "top_audintbus_sel", + "clk_26m", + "top_syspll1_d4", + "top_aud_k1_src_sel", + "top_aud_k2_src_sel", + "top_aud_k3_src_sel", + "top_aud_k4_src_sel", + "top_aud_k5_src_sel", + "top_aud_k6_src_sel", + "top_aud_k1_src_div", + "top_aud_k2_src_div", + "top_aud_k3_src_div", + "top_aud_k4_src_div", + "top_aud_k5_src_div", + "top_aud_k6_src_div", + "top_aud_i2s1_mclk", + "top_aud_i2s2_mclk", + "top_aud_i2s3_mclk", + "top_aud_i2s4_mclk", + "top_aud_i2s5_mclk", + "top_aud_i2s6_mclk", + "top_asm_m_sel", + "top_asm_h_sel", + "top_univpll2_d4", + "top_univpll2_d2", + "top_syspll_d5"; + +Example: + + afe: mt2701-afe-pcm@11220000 { + compatible = "mediatek,mt2701-audio"; + reg = <0 0x11220000 0 0x2000>, + <0 0x112A0000 0 0x20000>; + interrupts = , + ; + clocks = <&infracfg CLK_INFRA_AUDIO>, + <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>, + <&topckgen CLK_TOP_AUD_48K_TIMING>, + <&topckgen CLK_TOP_AUD_44K_TIMING>, + <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, + <&topckgen CLK_TOP_APLL_SEL>, + <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>, + <&topckgen CLK_TOP_HADDS2PLL_98M>, + <&topckgen CLK_TOP_HADDS2PLL_294M>, + <&topckgen CLK_TOP_AUDPLL>, + <&topckgen CLK_TOP_AUDPLL_D4>, + <&topckgen CLK_TOP_AUDPLL_D8>, + <&topckgen CLK_TOP_AUDPLL_D16>, + <&topckgen CLK_TOP_AUDPLL_D24>, + <&topckgen CLK_TOP_AUDINTBUS_SEL>, + <&clk26m>, + <&topckgen CLK_TOP_SYSPLL1_D4>, + <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, + <&topckgen CLK_TOP_AUD_I2S1_MCLK>, + <&topckgen CLK_TOP_AUD_I2S2_MCLK>, + <&topckgen CLK_TOP_AUD_I2S3_MCLK>, + <&topckgen CLK_TOP_AUD_I2S4_MCLK>, + <&topckgen CLK_TOP_AUD_I2S5_MCLK>, + <&topckgen CLK_TOP_AUD_I2S6_MCLK>, + <&topckgen CLK_TOP_ASM_M_SEL>, + <&topckgen CLK_TOP_ASM_H_SEL>, + <&topckgen CLK_TOP_UNIVPLL2_D4>, + <&topckgen CLK_TOP_UNIVPLL2_D2>, + <&topckgen CLK_TOP_SYSPLL_D5>; + + clock-names = "infra_sys_audio_clk", + "top_audio_mux1_sel", + "top_audio_mux2_sel", + "top_audio_mux1_div", + "top_audio_mux2_div", + "top_audio_48k_timing", + "top_audio_44k_timing", + "top_audpll_mux_sel", + "top_apll_sel", + "top_aud1_pll_98M", + "top_aud2_pll_90M", + "top_hadds2_pll_98M", + "top_hadds2_pll_294M", + "top_audpll", + "top_audpll_d4", + "top_audpll_d8", + "top_audpll_d16", + "top_audpll_d24", + "top_audintbus_sel", + "clk_26m", + "top_syspll1_d4", + "top_aud_k1_src_sel", + "top_aud_k2_src_sel", + "top_aud_k3_src_sel", + "top_aud_k4_src_sel", + "top_aud_k5_src_sel", + "top_aud_k6_src_sel", + "top_aud_k1_src_div", + "top_aud_k2_src_div", + "top_aud_k3_src_div", + "top_aud_k4_src_div", + "top_aud_k5_src_div", + "top_aud_k6_src_div", + "top_aud_i2s1_mclk", + "top_aud_i2s2_mclk", + "top_aud_i2s3_mclk", + "top_aud_i2s4_mclk", + "top_aud_i2s5_mclk", + "top_aud_i2s6_mclk", + "top_asm_m_sel", + "top_asm_h_sel", + "top_univpll2_d4", + "top_univpll2_d2", + "top_syspll_d5"; + }; diff --git a/Documentation/devicetree/bindings/sound/mt2701-cs42448.txt b/Documentation/devicetree/bindings/sound/mt2701-cs42448.txt new file mode 100644 index 000000000000..05574446ceb6 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt2701-cs42448.txt @@ -0,0 +1,43 @@ +MT2701 with CS42448 CODEC + +Required properties: +- compatible: "mediatek,mt2701-cs42448-machine" +- mediatek,platform: the phandle of MT2701 ASoC platform +- audio-routing: a list of the connections between audio +- mediatek,audio-codec: the phandles of cs42448 codec +- mediatek,audio-codec-bt-mrg the phandles of bt-sco dummy codec +- pinctrl-names: Should contain only one value - "default" +- pinctrl-0: Should specify pin control groups used for this controller. +- i2s1-in-sel-gpio1, i2s1-in-sel-gpio2: Should specify two gpio pins to + control I2S1-in mux. + +Example: + + sound:sound { + compatible = "mediatek,mt2701-cs42448-machine"; + mediatek,platform = <&afe>; + /* CS42448 Machine name */ + audio-routing = + "Line Out Jack", "AOUT1L", + "Line Out Jack", "AOUT1R", + "Line Out Jack", "AOUT2L", + "Line Out Jack", "AOUT2R", + "Line Out Jack", "AOUT3L", + "Line Out Jack", "AOUT3R", + "Line Out Jack", "AOUT4L", + "Line Out Jack", "AOUT4R", + "AIN1L", "AMIC", + "AIN1R", "AMIC", + "AIN2L", "Tuner In", + "AIN2R", "Tuner In", + "AIN3L", "Satellite Tuner In", + "AIN3R", "Satellite Tuner In", + "AIN3L", "AUX In", + "AIN3R", "AUX In"; + mediatek,audio-codec = <&cs42448>; + mediatek,audio-codec-bt-mrg = <&bt_sco_codec>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_pins_default>; + i2s1-in-sel-gpio1 = <&pio 53 0>; + i2s1-in-sel-gpio2 = <&pio 54 0>; + }; -- cgit v1.3-14-g43fede From 51ded0fbc18c5c05782c1c7eba30264b524added Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 29 Jun 2016 13:26:36 +0200 Subject: ASoC: Add DT bindings documentation for max98504 amplifier This patch adds DT bindings documentation for Maxim MAX98504 speaker amplifier. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/max98504.txt | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/max98504.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/max98504.txt b/Documentation/devicetree/bindings/sound/max98504.txt new file mode 100644 index 000000000000..583ed5fdfb28 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98504.txt @@ -0,0 +1,44 @@ +Maxim MAX98504 class D mono speaker amplifier + +This device supports I2C control interface and an IRQ output signal. It features +a PCM and PDM digital audio interface (DAI) and a differential analog input. + +Required properties: + + - compatible : "maxim,max98504" + - reg : should contain the I2C slave device address + - DVDD-supply, DIOVDD-supply, PVDD-supply: power supplies for the device, + as covered in ../regulator/regulator.txt + - interrupts : should specify the interrupt line the device is connected to, + as described in ../interrupt-controller/interrupts.txt + +Optional properties: + + - maxim,brownout-threshold - the PVDD brownout threshold, the value must be + from 0, 1...21 range, corresponding to 2.6V, 2.65V...3.65V voltage range + - maxim,brownout-attenuation - the brownout attenuation to the speaker gain + applied during the "attack hold" and "timed hold" phase, the value must be + from 0...6 (dB) range + - maxim,brownout-attack-hold-ms - the brownout attack hold phase time in ms, + 0...255 (VBATBROWN_ATTK_HOLD, register 0x0018) + - maxim,brownout-timed-hold-ms - the brownout timed hold phase time in ms, + 0...255 (VBATBROWN_TIME_HOLD, register 0x0019) + - maxim,brownout-release-rate-ms - the brownout release phase step time in ms, + 0...255 (VBATBROWN_RELEASE, register 0x001A) + +The default value when the above properties are not specified is 0, +the maxim,brownout-threshold property must be specified to actually enable +the PVDD brownout protection. + +Example: + + max98504@31 { + compatible = "maxim,max98504"; + reg = <0x31>; + interrupt-parent = <&gpio_bank_0>; + interrupts = <2 0>; + + DVDD-supply = <®ulator>; + DIOVDD-supply = <®ulator>; + PVDD-supply = <®ulator>; +}; -- cgit v1.3-14-g43fede From a3e2acc5e37b22b6808a0b8e46887c3577de9c9e Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Wed, 29 Jun 2016 13:04:29 -0700 Subject: ACPI / APEI: Add Boot Error Record Table (BERT) support ACPI/APEI is designed to verifiy/report H/W errors, like Corrected Error(CE) and Uncorrected Error(UC). It contains four tables: HEST, ERST, EINJ and BERT. The first three tables have been merged for a long time, but because of lacking BIOS support for BERT, the support for BERT is pending until now. Recently on ARM 64 platform it is has been supported. So here we come. Under normal circumstances, when a hardware error occurs, kernel will be notified via NMI, MCE or some other method, then kernel will process the error condition, report it, and recover it if possible. But sometime, the situation is so bad, so that firmware may choose to reset directly without notifying Linux kernel. Linux kernel can use the Boot Error Record Table (BERT) to get the un-notified hardware errors that occurred in a previous boot. In this patch, the error information is reported via printk. For more information about BERT, please refer to ACPI Specification version 6.0, section 18.3.1: http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf The following log is a BERT record after system reboot because of hitting a fatal memory error: BERT: Error records from previous boot: [Hardware Error]: It has been corrected by h/w and requires no further action [Hardware Error]: event severity: corrected [Hardware Error]: Error 0, type: recoverable [Hardware Error]: section_type: memory error [Hardware Error]: error_status: 0x0000000000000400 [Hardware Error]: physical_address: 0xffffffffffffffff [Hardware Error]: card: 1 module: 2 bank: 3 row: 1 column: 2 bit_position: 5 [Hardware Error]: error_type: 2, single-bit ECC [Tomasz Nowicki: Clear error status at the end of error handling] [Tony: Applied some cleanups suggested by Fu Wei] [Fu Wei: delete EXPORT_SYMBOL_GPL(bert_disable), improve the code] Signed-off-by: Huang Ying Signed-off-by: Tomasz Nowicki Signed-off-by: Chen, Gong Tested-by: Jonathan (Zhixiong) Zhang Signed-off-by: Fu Wei Tested-by: Tyler Baicar Reviewed-by: Borislav Petkov Signed-off-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- Documentation/kernel-parameters.txt | 3 + drivers/acpi/apei/Makefile | 2 +- drivers/acpi/apei/apei-internal.h | 2 +- drivers/acpi/apei/bert.c | 150 ++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 drivers/acpi/apei/bert.c (limited to 'Documentation') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..f565259167d7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -582,6 +582,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. bootmem_debug [KNL] Enable bootmem allocator debug messages. + bert_disable [ACPI] + Disable BERT OS support on buggy BIOSes. + bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards) bttv.radio= Most important insmod options are available as kernel args too. diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index 5d575a955940..e50573de25f1 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -3,4 +3,4 @@ obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o -apei-y := apei-base.o hest.o erst.o +apei-y := apei-base.o hest.o erst.o bert.o diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index 16129c78b489..6e9f14c0a71b 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -1,6 +1,6 @@ /* * apei-internal.h - ACPI Platform Error Interface internal - * definations. + * definitions. */ #ifndef APEI_INTERNAL_H diff --git a/drivers/acpi/apei/bert.c b/drivers/acpi/apei/bert.c new file mode 100644 index 000000000000..a05b5c0cf181 --- /dev/null +++ b/drivers/acpi/apei/bert.c @@ -0,0 +1,150 @@ +/* + * APEI Boot Error Record Table (BERT) support + * + * Copyright 2011 Intel Corp. + * Author: Huang Ying + * + * Under normal circumstances, when a hardware error occurs, the error + * handler receives control and processes the error. This gives OSPM a + * chance to process the error condition, report it, and optionally attempt + * recovery. In some cases, the system is unable to process an error. + * For example, system firmware or a management controller may choose to + * reset the system or the system might experience an uncontrolled crash + * or reset.The boot error source is used to report unhandled errors that + * occurred in a previous boot. This mechanism is described in the BERT + * table. + * + * For more information about BERT, please refer to ACPI Specification + * version 4.0, section 17.3.1 + * + * This file is licensed under GPLv2. + * + */ + +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#undef pr_fmt +#define pr_fmt(fmt) "BERT: " fmt + +static int bert_disable; + +static void __init bert_print_all(struct acpi_bert_region *region, + unsigned int region_len) +{ + struct acpi_hest_generic_status *estatus = + (struct acpi_hest_generic_status *)region; + int remain = region_len; + u32 estatus_len; + + if (!estatus->block_status) + return; + + while (remain > sizeof(struct acpi_bert_region)) { + if (cper_estatus_check(estatus)) { + pr_err(FW_BUG "Invalid error record.\n"); + return; + } + + estatus_len = cper_estatus_len(estatus); + if (remain < estatus_len) { + pr_err(FW_BUG "Truncated status block (length: %u).\n", + estatus_len); + return; + } + + pr_info_once("Error records from previous boot:\n"); + + cper_estatus_print(KERN_INFO HW_ERR, estatus); + + /* + * Because the boot error source is "one-time polled" type, + * clear Block Status of current Generic Error Status Block, + * once it's printed. + */ + estatus->block_status = 0; + + estatus = (void *)estatus + estatus_len; + /* No more error records. */ + if (!estatus->block_status) + return; + + remain -= estatus_len; + } +} + +static int __init setup_bert_disable(char *str) +{ + bert_disable = 1; + + return 0; +} +__setup("bert_disable", setup_bert_disable); + +static int __init bert_check_table(struct acpi_table_bert *bert_tab) +{ + if (bert_tab->header.length < sizeof(struct acpi_table_bert) || + bert_tab->region_length < sizeof(struct acpi_bert_region)) + return -EINVAL; + + return 0; +} + +static int __init bert_init(void) +{ + struct acpi_bert_region *boot_error_region; + struct acpi_table_bert *bert_tab; + unsigned int region_len; + acpi_status status; + int rc = 0; + + if (acpi_disabled) + return 0; + + if (bert_disable) { + pr_info("Boot Error Record Table support is disabled.\n"); + return 0; + } + + status = acpi_get_table(ACPI_SIG_BERT, 0, (struct acpi_table_header **)&bert_tab); + if (status == AE_NOT_FOUND) + return 0; + + if (ACPI_FAILURE(status)) { + pr_err("get table failed, %s.\n", acpi_format_exception(status)); + return -EINVAL; + } + + rc = bert_check_table(bert_tab); + if (rc) { + pr_err(FW_BUG "table invalid.\n"); + return rc; + } + + region_len = bert_tab->region_length; + if (!request_mem_region(bert_tab->address, region_len, "APEI BERT")) { + pr_err("Can't request iomem region <%016llx-%016llx>.\n", + (unsigned long long)bert_tab->address, + (unsigned long long)bert_tab->address + region_len - 1); + return -EIO; + } + + boot_error_region = ioremap_cache(bert_tab->address, region_len); + if (boot_error_region) { + bert_print_all(boot_error_region, region_len); + iounmap(boot_error_region); + } else { + rc = -ENOMEM; + } + + release_mem_region(bert_tab->address, region_len); + + return rc; +} + +late_initcall(bert_init); -- cgit v1.3-14-g43fede From 50f44e894ad06eb8b401308c3cfe5bceaaa26df2 Mon Sep 17 00:00:00 2001 From: Xinliang Liu Date: Mon, 20 Jun 2016 11:50:04 +0800 Subject: reset: hisilicon: Add media reset controller binding Add compatible for media reset controller. Actually, there are two reset controllers in hi6220 SoC: The peripheral reset controller bits are part of sysctrl registers. The media reset controller bits are part of mediactrl registers. So for the compatible part, it should contain "syscon" for both peripheral and media reset controller. Signed-off-by: Xinliang Liu Signed-off-by: Philipp Zabel --- Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt index e0b185a944ba..c25da39df707 100644 --- a/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt +++ b/Documentation/devicetree/bindings/reset/hisilicon,hi6220-reset.txt @@ -8,7 +8,9 @@ The reset controller registers are part of the system-ctl block on hi6220 SoC. Required properties: -- compatible: may be "hisilicon,hi6220-sysctrl" +- compatible: should be one of the following: + - "hisilicon,hi6220-sysctrl", "syscon" : For peripheral reset controller. + - "hisilicon,hi6220-mediactrl", "syscon" : For media reset controller. - reg: should be register base and length as documented in the datasheet - #reset-cells: 1, see below -- cgit v1.3-14-g43fede From a3828519c39aa9c85bae14bad2572d12dc0d1da6 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 27 Jun 2016 12:12:16 -0500 Subject: Documentation: dt: reset: Add TI syscon reset binding Add TI syscon reset controller binding. This will hook to the reset framework and use syscon/regmap to set reset bits. This allows reset control of individual SoC subsytems and devices with memory-mapped reset registers in a common register memory space. Signed-off-by: Andrew F. Davis Signed-off-by: Suman Anna Acked-by: Rob Herring Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/ti-syscon-reset.txt | 91 ++++++++++++++++++++++ include/dt-bindings/reset/ti-syscon.h | 38 +++++++++ 2 files changed, 129 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/ti-syscon-reset.txt create mode 100644 include/dt-bindings/reset/ti-syscon.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt b/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt new file mode 100644 index 000000000000..164c7f34c451 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt @@ -0,0 +1,91 @@ +TI SysCon Reset Controller +======================= + +Almost all SoCs have hardware modules that require reset control in addition +to clock and power control for their functionality. The reset control is +typically provided by means of memory-mapped I/O registers. These registers are +sometimes a part of a larger register space region implementing various +functionalities. This register range is best represented as a syscon node to +allow multiple entities to access their relevant registers in the common +register space. + +A SysCon Reset Controller node defines a device that uses a syscon node +and provides reset management functionality for various hardware modules +present on the SoC. + +SysCon Reset Controller Node +============================ +Each of the reset provider/controller nodes should be a child of a syscon +node and have the following properties. + +Required properties: +-------------------- + - compatible : Should be, + "ti,k2e-pscrst" + "ti,k2l-pscrst" + "ti,k2hk-pscrst" + "ti,syscon-reset" + - #reset-cells : Should be 1. Please see the reset consumer node below + for usage details + - ti,reset-bits : Contains the reset control register information + Should contain 7 cells for each reset exposed to + consumers, defined as: + Cell #1 : offset of the reset assert control + register from the syscon register base + Cell #2 : bit position of the reset in the reset + assert control register + Cell #3 : offset of the reset deassert control + register from the syscon register base + Cell #4 : bit position of the reset in the reset + deassert control register + Cell #5 : offset of the reset status register + from the syscon register base + Cell #6 : bit position of the reset in the + reset status register + Cell #7 : Flags used to control reset behavior, + availible flags defined in the DT include + file + +SysCon Reset Consumer Nodes +=========================== +Each of the reset consumer nodes should have the following properties, +in addition to their own properties. + +Required properties: +-------------------- + - resets : A phandle to the reset controller node and an index number + to a reset specifier as defined above. + +Please also refer to Documentation/devicetree/bindings/reset/reset.txt for +common reset controller usage by consumers. + +Example: +-------- +The following example demonstrates a syscon node, the reset controller node +using the syscon node, and a consumer (a DSP device) on the TI Keystone 2 +Edison SoC. + +/ { + soc { + psc: power-sleep-controller@02350000 { + compatible = "syscon", "simple-mfd"; + reg = <0x02350000 0x1000>; + + pscrst: psc-reset { + compatible = "ti,k2e-pscrst", "ti,syscon-reset"; + #reset-cells = <1>; + + ti,reset-bits = < + 0xa3c 8 0xa3c 8 0x83c 8 (ASSERT_SET|DEASSERT_CLEAR|STATUS_SET) /* 0: pcrst-dsp0 */ + 0xa40 5 0xa44 3 0 0 (ASSERT_SET|DEASSERT_CLEAR|STATUS_NONE) /* 1: pcrst-example */ + >; + }; + }; + + dsp0: dsp0 { + ... + resets = <&pscrst 0>; + ... + }; + }; +}; diff --git a/include/dt-bindings/reset/ti-syscon.h b/include/dt-bindings/reset/ti-syscon.h new file mode 100644 index 000000000000..884fd91df8e9 --- /dev/null +++ b/include/dt-bindings/reset/ti-syscon.h @@ -0,0 +1,38 @@ +/* + * TI Syscon Reset definitions + * + * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __DT_BINDINGS_RESET_TI_SYSCON_H__ +#define __DT_BINDINGS_RESET_TI_SYSCON_H__ + +/* + * The reset does not support the feature and corresponding + * values are not valid + */ +#define ASSERT_NONE (1 << 0) +#define DEASSERT_NONE (1 << 1) +#define STATUS_NONE (1 << 2) + +/* When set this function is activated by setting(vs clearing) this bit */ +#define ASSERT_SET (1 << 3) +#define DEASSERT_SET (1 << 4) +#define STATUS_SET (1 << 5) + +/* The following are the inverse of the above and are added for consistency */ +#define ASSERT_CLEAR (0 << 3) +#define DEASSERT_CLEAR (0 << 4) +#define STATUS_CLEAR (0 << 5) + +#endif -- cgit v1.3-14-g43fede From 38c81719b1658fdff7d3509b8a0c6294ce29c3d4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 15 Jun 2016 23:11:20 +0200 Subject: ASoC: sunxi: Add A10 I2S controller binding documentation Introduce the device tree binding for the I2S controller found in the Allwinner A10 and later SoCs. Signed-off-by: Maxime Ripard Acked-by: Rob Herring Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/sun4i-i2s.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/sun4i-i2s.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt new file mode 100644 index 000000000000..7b526ec64991 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt @@ -0,0 +1,34 @@ +* Allwinner A10 I2S controller + +The I2S bus (Inter-IC sound bus) is a serial link for digital +audio data transfer between devices in the system. + +Required properties: + +- compatible: should be one of the followings + - "allwinner,sun4i-a10-i2s" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: should contain the I2S interrupt. +- dmas: DMA specifiers for tx and rx dma. See the DMA client binding, + Documentation/devicetree/bindings/dma/dma.txt +- dma-names: should include "tx" and "rx". +- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names. +- clock-names: should contain followings: + - "apb" : clock for the I2S bus interface + - "mod" : module clock for the I2S controller +- #sound-dai-cells : Must be equal to 0 + +Example: + +i2s0: i2s@01c22400 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun4i-a10-i2s"; + reg = <0x01c22400 0x400>; + interrupts = ; + clocks = <&apb0_gates 3>, <&i2s0_clk>; + clock-names = "apb", "mod"; + dmas = <&dma SUN4I_DMA_NORMAL 3>, + <&dma SUN4I_DMA_NORMAL 3>; + dma-names = "rx", "tx"; +}; -- cgit v1.3-14-g43fede From a92e7c3d82a1313ab1954e5cdfd8f04efdb4ca78 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Tue, 28 Jun 2016 11:41:12 +0900 Subject: spi: s3c64xx: consider the case when the CS line is not connected When the CS line is not connected, it is not needed to enable or disable the chip selection functionality from the s3c64xx devices in order to perform a transfer. Set the CS controller logically always enabled already during initialization (by writing '0' in the S3C64XX_SPI_SLAVE_SEL register) and never disable it. Signed-off-by: Andi Shyti Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-samsung.txt | 3 +++ drivers/spi/spi-s3c64xx.c | 9 ++++++++- include/linux/platform_data/spi-s3c64xx.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt index 6dbdeb3c361a..930bc7349271 100644 --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt +++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt @@ -40,6 +40,9 @@ Optional Board Specific Properties: - cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt) +- no-cs-readback: the CS line is disconnected, therefore the device should not + operate based on CS signalling. + SPI Controller specific data in SPI slave nodes: - The spi slave nodes should provide the following information which is required diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 972367d5c7f2..14269b07804c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -315,6 +315,9 @@ static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi->master); + if (sdd->cntrlr_info->no_cs) + return; + if (enable) { if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) { writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); @@ -960,7 +963,9 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) sdd->cur_speed = 0; - if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) + if (sci->no_cs) + writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); + else if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); /* Disable Interrupts - we use Polling if not DMA mode */ @@ -1015,6 +1020,8 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev) sci->num_cs = temp; } + sci->no_cs = of_property_read_bool(dev->of_node, "broken-cs"); + return sci; } #else diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index fb5625bcca9a..5c1e21c87270 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -38,6 +38,7 @@ struct s3c64xx_spi_csinfo { struct s3c64xx_spi_info { int src_clk_nr; int num_cs; + bool no_cs; int (*cfg_gpio)(void); dma_filter_fn filter; void *dma_tx; -- cgit v1.3-14-g43fede From a74a198249c473fba092ee549068cea30d54f07e Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Wed, 22 Jun 2016 22:22:18 +0300 Subject: pwm: omap-dmtimer: Allow for setting dmtimer clock source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OMAP GP timers can have different input clocks that allow different PWM frequencies. However, there is no other way of setting the clock source but through clocks or clock-names properties of the timer itself. This limits PWM functionality to only the frequencies allowed by the particular clock source. Allowing setting the clock source by PWM rather than by timer allows different PWMs to have different ranges by not hard-wiring the clock source to the timer. Signed-off-by: Ivaylo Dimitrov Acked-by: Rob Herring Acked-by: Thierry Reding Acked-by: Pali Rohár Signed-off-by: Tony Lindgren --- Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt | 4 ++++ drivers/pwm/pwm-omap-dmtimer.c | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt b/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt index 5befb538db95..2e53324fb720 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt @@ -9,6 +9,10 @@ Required properties: Optional properties: - ti,prescaler: Should be a value between 0 and 7, see the timers datasheet +- ti,clock-source: Set dmtimer parent clock, values between 0 and 2: + - 0x00 - high-frequency system clock (timer_sys_ck) + - 0x01 - 32-kHz always-on clock (timer_32k_ck) + - 0x02 - external clock (timer_ext_ck, OMAP2 only) Example: pwm9: dmtimer-pwm@9 { diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index 3e95090cd7cf..5ad42f33e70c 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -245,7 +245,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) struct pwm_omap_dmtimer_chip *omap; struct pwm_omap_dmtimer_pdata *pdata; pwm_omap_dmtimer *dm_timer; - u32 prescaler; + u32 v; int status; pdata = dev_get_platdata(&pdev->dev); @@ -306,10 +306,12 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) if (pm_runtime_active(&omap->dm_timer_pdev->dev)) omap->pdata->stop(omap->dm_timer); - /* setup dmtimer prescaler */ - if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", - &prescaler)) - omap->pdata->set_prescaler(omap->dm_timer, prescaler); + if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v)) + omap->pdata->set_prescaler(omap->dm_timer, v); + + /* setup dmtimer clock source */ + if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v)) + omap->pdata->set_source(omap->dm_timer, v); omap->chip.dev = &pdev->dev; omap->chip.ops = &pwm_omap_dmtimer_ops; -- cgit v1.3-14-g43fede From b5406176989da601736db862643d3d7ee8335815 Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Wed, 22 Jun 2016 22:22:20 +0300 Subject: ir-rx51: add DT support to driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the upcoming removal of legacy boot, lets add support to one of the last N900 drivers remaining without it. As the driver still uses omap dmtimer, add auxdata as well. Signed-off-by: Ivaylo Dimitrov Acked-by: Rob Herring Acked-by: Pali Rohár Signed-off-by: Tony Lindgren --- .../devicetree/bindings/media/nokia,n900-ir | 20 ++++++++++++++++++++ arch/arm/mach-omap2/pdata-quirks.c | 6 +----- drivers/media/rc/ir-rx51.c | 11 ++++++++++- 3 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/nokia,n900-ir (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/media/nokia,n900-ir b/Documentation/devicetree/bindings/media/nokia,n900-ir new file mode 100644 index 000000000000..13a18ce37dd1 --- /dev/null +++ b/Documentation/devicetree/bindings/media/nokia,n900-ir @@ -0,0 +1,20 @@ +Device-Tree bindings for LIRC TX driver for Nokia N900(RX51) + +Required properties: + - compatible: should be "nokia,n900-ir". + - pwms: specifies PWM used for IR signal transmission. + +Example node: + + pwm9: dmtimer-pwm@9 { + compatible = "ti,omap-dmtimer-pwm"; + ti,timers = <&timer9>; + ti,clock-source = <0x00>; /* timer_sys_ck */ + #pwm-cells = <3>; + }; + + ir: n900-ir { + compatible = "nokia,n900-ir"; + + pwms = <&pwm9 0 26316 0>; /* 38000 Hz */ + }; diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 278bb8f3b77b..0d7b05a36b99 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -273,8 +273,6 @@ static struct platform_device omap3_rom_rng_device = { }, }; -static struct platform_device rx51_lirc_device; - static void __init nokia_n900_legacy_init(void) { hsmmc2_internal_input_clk(); @@ -293,10 +291,7 @@ static void __init nokia_n900_legacy_init(void) pr_info("RX-51: Registering OMAP3 HWRNG device\n"); platform_device_register(&omap3_rom_rng_device); - } - - platform_device_register(&rx51_lirc_device); } static void __init omap3_tao3530_legacy_init(void) @@ -531,6 +526,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { &omap3_iommu_pdata), OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x4809c000, "4809c000.mmc", &mmc_pdata[0]), OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x480b4000, "480b4000.mmc", &mmc_pdata[1]), + OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_lirc_data), /* Only on am3517 */ OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c index 5096ef3108d9..1cbb43d0a350 100644 --- a/drivers/media/rc/ir-rx51.c +++ b/drivers/media/rc/ir-rx51.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -478,6 +479,14 @@ static int lirc_rx51_remove(struct platform_device *dev) return lirc_unregister_driver(lirc_rx51_driver.minor); } +static const struct of_device_id lirc_rx51_match[] = { + { + .compatible = "nokia,n900-ir", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, lirc_rx51_match); + struct platform_driver lirc_rx51_platform_driver = { .probe = lirc_rx51_probe, .remove = lirc_rx51_remove, @@ -485,7 +494,7 @@ struct platform_driver lirc_rx51_platform_driver = { .resume = lirc_rx51_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, + .of_match_table = of_match_ptr(lirc_rx51_match), }, }; module_platform_driver(lirc_rx51_platform_driver); -- cgit v1.3-14-g43fede From e698b8a43659f9ece192fcab215abcadac8f88d7 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 30 Jun 2016 08:53:27 +0200 Subject: vfs: document ->d_real() Add missing documentation for the d_op->d_real() method and d_real() helper. Signed-off-by: Miklos Szeredi --- Documentation/filesystems/Locking | 3 +++ Documentation/filesystems/vfs.txt | 20 ++++++++++++++++++++ include/linux/dcache.h | 14 +++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 75eea7ce3d7c..898d3cecd8a6 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -20,6 +20,8 @@ prototypes: char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); struct vfsmount *(*d_automount)(struct path *path); int (*d_manage)(struct dentry *, bool); + struct dentry *(*d_real)(struct dentry *, const struct inode *, + unsigned int); locking rules: rename_lock ->d_lock may block rcu-walk @@ -34,6 +36,7 @@ d_iput: no no yes no d_dname: no no no no d_automount: no no yes no d_manage: no no yes (ref-walk) maybe +d_real no no yes no --------------------------- inode_operations --------------------------- prototypes: diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index c61a223ef3ff..1c934dd2c47d 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -938,6 +938,8 @@ struct dentry_operations { char *(*d_dname)(struct dentry *, char *, int); struct vfsmount *(*d_automount)(struct path *); int (*d_manage)(struct dentry *, bool); + struct dentry *(*d_real)(struct dentry *, const struct inode *, + unsigned int); }; d_revalidate: called when the VFS needs to revalidate a dentry. This @@ -1060,6 +1062,24 @@ struct dentry_operations { This function is only used if DCACHE_MANAGE_TRANSIT is set on the dentry being transited from. + d_real: overlay/union type filesystems implement this method to return one of + the underlying dentries hidden by the overlay. It is used in three + different modes: + + Called from open it may need to copy-up the file depending on the + supplied open flags. This mode is selected with a non-zero flags + argument. In this mode the d_real method can return an error. + + Called from file_dentry() it returns the real dentry matching the inode + argument. The real dentry may be from a lower layer already copied up, + but still referenced from the file. This mode is selected with a + non-NULL inode argument. This will always succeed. + + With NULL inode and zero flags the topmost real underlying dentry is + returned. This will always succeed. + + This method is never called with both non-NULL inode and non-zero flags. + Example : static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen) diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 45b22de15ede..14df83609c7f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -139,7 +139,8 @@ struct dentry_operations { char *(*d_dname)(struct dentry *, char *, int); struct vfsmount *(*d_automount)(struct path *); int (*d_manage)(struct dentry *, bool); - struct dentry *(*d_real)(struct dentry *, const struct inode *, unsigned int); + struct dentry *(*d_real)(struct dentry *, const struct inode *, + unsigned int); } ____cacheline_aligned; /* @@ -554,6 +555,17 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper) return upper; } +/** + * d_real - Return the real dentry + * @dentry: the dentry to query + * @inode: inode to select the dentry from multiple layers (can be NULL) + * @flags: open flags to control copy-up behavior + * + * If dentry is on an union/overlay, then return the underlying, real dentry. + * Otherwise return the dentry itself. + * + * See also: Documentation/filesystems/vfs.txt + */ static inline struct dentry *d_real(struct dentry *dentry, const struct inode *inode, unsigned int flags) -- cgit v1.3-14-g43fede From 0cac643c102c0632dc2cc81e2490b0fec1cac0af Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 30 Jun 2016 08:53:28 +0200 Subject: vfs: clean up documentation Signed-off-by: Miklos Szeredi --- Documentation/filesystems/Locking | 2 -- Documentation/filesystems/vfs.txt | 24 ++++++++---------------- 2 files changed, 8 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 898d3cecd8a6..d4def7b78a62 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -69,7 +69,6 @@ prototypes: struct file *, unsigned open_flag, umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); - int (*dentry_open)(struct dentry *, struct file *, const struct cred *); locking rules: all may block @@ -98,7 +97,6 @@ fiemap: no update_time: no atomic_open: yes tmpfile: no -dentry_open: no Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on victim. diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 1c934dd2c47d..01c4f1741c20 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -364,7 +364,6 @@ struct inode_operations { int (*atomic_open)(struct inode *, struct dentry *, struct file *, unsigned open_flag, umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); - int (*dentry_open)(struct dentry *, struct file *, const struct cred *); }; Again, all methods are called without any locks being held, unless @@ -696,13 +695,6 @@ struct address_space_operations { but instead uses bmap to find out where the blocks in the file are and uses those addresses directly. - dentry_open: *WARNING: probably going away soon, do not use!* This is an - alternative to f_op->open(), the difference is that this method may open - a file not necessarily originating from the same filesystem as the one - i_op->open() was called on. It may be useful for stacking filesystems - which want to allow native I/O directly on underlying files. - - invalidatepage: If a page has PagePrivate set, then invalidatepage will be called when part or all of the page is to be removed from the address space. This generally corresponds to either a @@ -1024,6 +1016,14 @@ struct dentry_operations { at the end of the buffer, and returns a pointer to the first char. dynamic_dname() helper function is provided to take care of this. + Example : + + static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen) + { + return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", + dentry->d_inode->i_ino); + } + d_automount: called when an automount dentry is to be traversed (optional). This should create a new VFS mount record and return the record to the caller. The caller is supplied with a path parameter giving the @@ -1080,14 +1080,6 @@ struct dentry_operations { This method is never called with both non-NULL inode and non-zero flags. -Example : - -static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen) -{ - return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", - dentry->d_inode->i_ino); -} - Each dentry has a pointer to its parent dentry, as well as a hash list of child dentries. Child dentries are basically like files in a directory. -- cgit v1.3-14-g43fede From 29cac32b67de6675b79f665567305fa57283f327 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 9 May 2016 18:42:11 +0800 Subject: batman-adv: document sysfs files in alphabetical order Also update obsolete email address. Signed-off-by: Marek Lindner Acked-by: Antonio Quartulli Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- Documentation/ABI/testing/sysfs-class-net-batman-adv | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv index 518f6a1dbc0c..77d3083304df 100644 --- a/Documentation/ABI/testing/sysfs-class-net-batman-adv +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -1,13 +1,4 @@ -What: /sys/class/net//batman-adv/throughput_override -Date: Feb 2014 -Contact: Antonio Quartulli -description: - Defines the throughput value to be used by B.A.T.M.A.N. V - when estimating the link throughput using this interface. - If the value is set to 0 then batman-adv will try to - estimate the throughput by itself. - What: /sys/class/net//batman-adv/elp_interval Date: Feb 2014 Contact: Linus Lüssing @@ -28,3 +19,12 @@ Description: The /sys/class/net//batman-adv/mesh_iface file displays the batman mesh interface this currently is associated with. + +What: /sys/class/net//batman-adv/throughput_override +Date: Feb 2014 +Contact: Antonio Quartulli +description: + Defines the throughput value to be used by B.A.T.M.A.N. V + when estimating the link throughput using this interface. + If the value is set to 0 then batman-adv will try to + estimate the throughput by itself. -- cgit v1.3-14-g43fede From 21c02be7cfc5c6b7927290716a243674f134242b Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 9 May 2016 18:42:12 +0800 Subject: batman-adv: update elp interval documentation Signed-off-by: Marek Lindner Acked-by: Antonio Quartulli Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- Documentation/ABI/testing/sysfs-class-net-batman-adv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv index 77d3083304df..898106849e27 100644 --- a/Documentation/ABI/testing/sysfs-class-net-batman-adv +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -4,7 +4,7 @@ Date: Feb 2014 Contact: Linus Lüssing Description: Defines the interval in milliseconds in which batman - sends its probing packets for link quality measurements. + emits probing packets for neighbor sensing (ELP). What: /sys/class/net//batman-adv/iface_status Date: May 2010 -- cgit v1.3-14-g43fede From caf8a6c4778883bee0975d0daf1042f1ea321444 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 29 Jun 2016 10:17:50 +0100 Subject: dt-bindings: display: Update Tegra DPAUX documentation Update the DPAUX compatibility string information for Tegra124, Tegra132 and Tegra210. Signed-off-by: Jon Hunter Acked-by: Rob Herring Signed-off-by: Thierry Reding --- .../devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt index a3bd8c050c4e..275f45680892 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt @@ -226,9 +226,9 @@ of the following host1x client modules: - nvidia,dpaux: phandle to a DispayPort AUX interface - dpaux: DisplayPort AUX interface - - compatible: For Tegra124, must contain "nvidia,tegra124-dpaux". Otherwise, - must contain '"nvidia,-dpaux", "nvidia,tegra124-dpaux"', where - is tegra132. + - compatible : Should contain one of the following: + - "nvidia,tegra124-dpaux": for Tegra124 and Tegra132 + - "nvidia,tegra210-dpaux": for Tegra210 - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. - clocks: Must contain an entry for each entry in clock-names. -- cgit v1.3-14-g43fede From 6cb68e46a987f61092a1812ebe5371542c7e380d Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 29 Jun 2016 10:17:54 +0100 Subject: dt-bindings: Add bindings for Tegra DPAUX pinctrl driver On Tegra124, Tegra132 and Tegra210 devices the pads used by the Display Port Auxiliary (DPAUX) channel are multiplexed such that they can also be used by one of the internal I2C controllers. Note that this is different from I2C-over-AUX supported by the DPAUX controller. The register that configures these pads is part of the DPAUX controllers register set and so a pinctrl driver is being added for the DPAUX device to share these pads. Add the device-tree binding documentation for the DPAUX pad controller. Although there is only one group of pads associated with the DPAUX that can be multiplexed, the group still needs to be described by the binding. If the 'groups' property is not present in the binding, then the pads will not be allocated by the pinctrl core for a client and this would allow another client to re-configure the same pads that may already be in-use. Please note that although the "off" function for the DPAUX pads is not technically a pin-mux setting but more of a pin-conf setting it is simpler to expose these as a function so that the user can simply select either "aux", "i2c" or "off" as the current function/mode. Update the main DPAUX binding documentation to reference the DPAUX pad controller binding document and add the 'i2c-bus' subnode. The 'i2c-bus' subnode is used for populating I2C slaves for the DPAUX device so that the I2C driver core does not attempt to add the DPAUX pad controller nodes as I2C slaves. Signed-off-by: Jon Hunter Acked-by: Rob Herring Signed-off-by: Thierry Reding --- .../display/tegra/nvidia,tegra20-host1x.txt | 6 +++ .../pinctrl/nvidia,tegra124-dpaux-padctl.txt | 60 ++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt index 275f45680892..d0f1dc62550a 100644 --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt @@ -241,6 +241,12 @@ of the following host1x client modules: - reset-names: Must include the following entries: - dpaux - vdd-supply: phandle of a supply that powers the DisplayPort link + - i2c-bus: Subnode where I2C slave devices are listed. This subnode + must be always present. If there are no I2C slave devices, an empty + node should be added. See ../../i2c/i2c.txt for more information. + + See ../pinctrl/nvidia,tegra124-dpaux-padctl.txt for information + regarding the DPAUX pad controller bindings. Example: diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt new file mode 100644 index 000000000000..f2abdaee9022 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt @@ -0,0 +1,60 @@ +Device tree binding for NVIDIA Tegra DPAUX pad controller +======================================================== + +The Tegra Display Port Auxiliary (DPAUX) pad controller manages two pins +which can be assigned to either the DPAUX channel or to an I2C +controller. + +This document defines the device-specific binding for the DPAUX pad +controller. Refer to pinctrl-bindings.txt in this directory for generic +information about pin controller device tree bindings. Please refer to +the binding document ../display/tegra/nvidia,tegra20-host1x.txt for more +details on the DPAUX binding. + +Pin muxing: +----------- + +Child nodes contain the pinmux configurations following the conventions +from the pinctrl-bindings.txt document. + +Since only three configurations are possible, only three child nodes are +needed to describe the pin mux'ing options for the DPAUX pads. +Furthermore, given that the pad functions are only applicable to a +single set of pads, the child nodes only need to describe the pad group +the functions are being applied to rather than the individual pads. + +Required properties: +- groups: Must be "dpaux-io" +- function: Must be either "aux", "i2c" or "off". + +Example: +-------- + + dpaux@545c0000 { + ... + + state_dpaux_aux: pinmux-aux { + groups = "dpaux-io"; + function = "aux"; + }; + + state_dpaux_i2c: pinmux-i2c { + groups = "dpaux-io"; + function = "i2c"; + }; + + state_dpaux_off: pinmux-off { + groups = "dpaux-io"; + function = "off"; + }; + }; + + ... + + i2c@7000d100 { + ... + pinctrl-0 = <&state_dpaux_i2c>; + pinctrl-1 = <&state_dpaux_off>; + pinctrl-names = "default", "idle"; + status = "disabled"; + }; -- cgit v1.3-14-g43fede From 9b9a553c902e79867b6527301fe64e45be23e36b Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 29 Jun 2016 23:36:20 +0900 Subject: net: netcp: Fix a typo in keystone-netcp.txt This patch fix a spelling typo in keystone-netcp.txt Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/keystone-netcp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/net/keystone-netcp.txt b/Documentation/devicetree/bindings/net/keystone-netcp.txt index b30ab6b5cbfa..04ba1dc34fd6 100644 --- a/Documentation/devicetree/bindings/net/keystone-netcp.txt +++ b/Documentation/devicetree/bindings/net/keystone-netcp.txt @@ -2,7 +2,7 @@ This document describes the device tree bindings associated with the keystone network coprocessor(NetCP) driver support. The network coprocessor (NetCP) is a hardware accelerator that processes -Ethernet packets. NetCP has a gigabit Ethernet (GbE) subsytem with a ethernet +Ethernet packets. NetCP has a gigabit Ethernet (GbE) subsystem with a ethernet switch sub-module to send and receive packets. NetCP also includes a packet accelerator (PA) module to perform packet classification operations such as header matching, and packet modification operations such as checksum -- cgit v1.3-14-g43fede From bc2b7dab629a51e8beb5fda4222c62a23b729f26 Mon Sep 17 00:00:00 2001 From: Gregor Boirie Date: Wed, 9 Mar 2016 19:05:49 +0100 Subject: iio:core: timestamping clock selection support Adds a new per-device sysfs attribute "current_timestamp_clock" to allow userspace to select a particular POSIX clock for buffered samples and events timestamping. Following clocks, as listed in clock_gettime(2), are supported: CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME and CLOCK_TAI. Signed-off-by: Gregor Boirie Acked-by: Sanchayan Maity Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 7 + Documentation/DocBook/iio.tmpl | 2 +- drivers/iio/accel/bma180.c | 2 +- drivers/iio/accel/bmc150-accel-core.c | 4 +- drivers/iio/accel/kxcjk-1013.c | 2 +- drivers/iio/accel/mma7455_core.c | 3 +- drivers/iio/accel/mma8452.c | 4 +- drivers/iio/accel/mma9551.c | 2 +- drivers/iio/accel/mma9553.c | 2 +- drivers/iio/adc/ad7291.c | 2 +- drivers/iio/adc/ad7298.c | 2 +- drivers/iio/adc/ad7476.c | 2 +- drivers/iio/adc/ad7887.c | 2 +- drivers/iio/adc/ad7923.c | 2 +- drivers/iio/adc/ad799x.c | 4 +- drivers/iio/adc/cc10001_adc.c | 2 +- drivers/iio/adc/hi8435.c | 2 +- drivers/iio/adc/ina2xx-adc.c | 6 +- drivers/iio/adc/max1363.c | 5 +- drivers/iio/adc/ti-adc081c.c | 3 +- drivers/iio/adc/ti-ads1015.c | 3 +- drivers/iio/adc/vf610_adc.c | 3 +- drivers/iio/adc/xilinx-xadc-events.c | 4 +- drivers/iio/chemical/atlas-ph-sensor.c | 2 +- drivers/iio/common/st_sensors/st_sensors_buffer.c | 2 +- drivers/iio/common/st_sensors/st_sensors_trigger.c | 2 +- drivers/iio/dac/ad5421.c | 6 +- drivers/iio/dac/ad5504.c | 2 +- drivers/iio/dummy/iio_simple_dummy_buffer.c | 3 +- drivers/iio/dummy/iio_simple_dummy_events.c | 2 +- drivers/iio/gyro/bmg160_core.c | 30 ++-- drivers/iio/iio_core.h | 3 + drivers/iio/imu/bmi160/bmi160_core.c | 3 +- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 2 +- drivers/iio/industrialio-core.c | 179 ++++++++++++++++++++- drivers/iio/industrialio-event.c | 19 ++- drivers/iio/industrialio-trigger.c | 2 +- drivers/iio/light/acpi-als.c | 2 +- drivers/iio/light/adjd_s311.c | 2 +- drivers/iio/light/apds9300.c | 2 +- drivers/iio/light/apds9960.c | 4 +- drivers/iio/light/cm36651.c | 2 +- drivers/iio/light/gp2ap020a00f.c | 8 +- drivers/iio/light/isl29125.c | 2 +- drivers/iio/light/lm3533-als.c | 2 +- drivers/iio/light/ltr501.c | 7 +- drivers/iio/light/max44000.c | 3 +- drivers/iio/light/opt3001.c | 4 +- drivers/iio/light/stk3310.c | 2 +- drivers/iio/light/tcs3414.c | 2 +- drivers/iio/light/tcs3472.c | 2 +- drivers/iio/light/tsl2563.c | 2 +- drivers/iio/light/us5182d.c | 2 +- drivers/iio/magnetometer/ak8975.c | 3 +- drivers/iio/magnetometer/hmc5843_core.c | 2 +- drivers/iio/magnetometer/mag3110.c | 2 +- drivers/iio/pressure/mpl3115.c | 2 +- drivers/iio/pressure/ms5611_core.c | 3 +- drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 2 +- drivers/iio/proximity/sx9500.c | 4 +- drivers/staging/iio/accel/lis3l02dq_core.c | 2 +- drivers/staging/iio/accel/sca3000_core.c | 2 +- drivers/staging/iio/adc/ad7280a.c | 8 +- drivers/staging/iio/adc/ad7606_ring.c | 3 +- drivers/staging/iio/adc/ad7816.c | 3 +- drivers/staging/iio/addac/adt7316.c | 4 +- drivers/staging/iio/cdc/ad7150.c | 2 +- drivers/staging/iio/light/tsl2x7x_core.c | 2 +- include/linux/iio/iio.h | 22 ++- 69 files changed, 327 insertions(+), 114 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index e7f590c6ef8e..fee35c00cc4e 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -32,6 +32,13 @@ Description: Description of the physical chip / device for device X. Typically a part number. +What: /sys/bus/iio/devices/iio:deviceX/timestamp_clock +KernelVersion: 4.5 +Contact: linux-iio@vger.kernel.org +Description: + String identifying current posix clock used to timestamp + buffered samples and events for device X. + What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency What: /sys/bus/iio/devices/triggerX/sampling_frequency diff --git a/Documentation/DocBook/iio.tmpl b/Documentation/DocBook/iio.tmpl index f525bf56d1dd..e2ab6a1f223e 100644 --- a/Documentation/DocBook/iio.tmpl +++ b/Documentation/DocBook/iio.tmpl @@ -594,7 +594,7 @@ irqreturn_t sensor_iio_pollfunc(int irq, void *p) { - pf->timestamp = iio_get_time_ns(); + pf->timestamp = iio_get_time_ns((struct indio_dev *)p); return IRQ_WAKE_THREAD; } diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index f04b88406995..e3f88ba5faf3 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -654,7 +654,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bma180_data *data = iio_priv(indio_dev); - int64_t time_ns = iio_get_time_ns(); + s64 time_ns = iio_get_time_ns(indio_dev); int bit, ret, i = 0; mutex_lock(&data->mutex); diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 197e693e7e7b..bf17aae66145 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -901,7 +901,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev, */ if (!irq) { data->old_timestamp = data->timestamp; - data->timestamp = iio_get_time_ns(); + data->timestamp = iio_get_time_ns(indio_dev); } /* @@ -1303,7 +1303,7 @@ static irqreturn_t bmc150_accel_irq_handler(int irq, void *private) int i; data->old_timestamp = data->timestamp; - data->timestamp = iio_get_time_ns(); + data->timestamp = iio_get_time_ns(indio_dev); for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { if (data->triggers[i].enabled) { diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index bfe219a8bea2..765a72362dc6 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -1129,7 +1129,7 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private) struct iio_dev *indio_dev = private; struct kxcjk1013_data *data = iio_priv(indio_dev); - data->timestamp = iio_get_time_ns(); + data->timestamp = iio_get_time_ns(indio_dev); if (data->dready_trigger_on) iio_trigger_poll(data->dready_trig); diff --git a/drivers/iio/accel/mma7455_core.c b/drivers/iio/accel/mma7455_core.c index c902f54c23f5..6551085bedd7 100644 --- a/drivers/iio/accel/mma7455_core.c +++ b/drivers/iio/accel/mma7455_core.c @@ -97,7 +97,8 @@ static irqreturn_t mma7455_trigger_handler(int irq, void *p) if (ret) goto done; - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 799fe64fc286..c0df28328368 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -917,7 +917,7 @@ static int mma8452_write_event_config(struct iio_dev *indio_dev, static void mma8452_transient_interrupt(struct iio_dev *indio_dev) { struct mma8452_data *data = iio_priv(indio_dev); - s64 ts = iio_get_time_ns(); + s64 ts = iio_get_time_ns(indio_dev); int src; src = i2c_smbus_read_byte_data(data->client, data->chip_info->ev_src); @@ -997,7 +997,7 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p) goto done; iio_push_to_buffers_with_timestamp(indio_dev, buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index d899a4d4307f..bf2704435629 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -391,7 +391,7 @@ static irqreturn_t mma9551_event_handler(int irq, void *private) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1), IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); out: mutex_unlock(&data->mutex); diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index bb05f3efddca..36bf19733be0 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -1001,7 +1001,7 @@ static irqreturn_t mma9553_irq_handler(int irq, void *private) struct iio_dev *indio_dev = private; struct mma9553_data *data = iio_priv(indio_dev); - data->timestamp = iio_get_time_ns(); + data->timestamp = iio_get_time_ns(indio_dev); /* * Since we only configure the interrupt pin when an * event is enabled, we are sure we have at least diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index c0eabf156702..037630932749 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -115,7 +115,7 @@ static irqreturn_t ad7291_event_handler(int irq, void *private) u16 t_status, v_status; u16 command; int i; - s64 timestamp = iio_get_time_ns(); + s64 timestamp = iio_get_time_ns(indio_dev); if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status)) return IRQ_HANDLED; diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index 62bb8f7ce4a0..5dd0742da75a 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -163,7 +163,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) goto done; iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 810c9a9fa62f..a819be288577 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -70,7 +70,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) goto done; iio_push_to_buffers_with_timestamp(indio_dev, st->data, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index ee2ccc19fab6..1bc363b0a4c1 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -122,7 +122,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) goto done; iio_push_to_buffers_with_timestamp(indio_dev, st->data, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index ff444c19d749..133711680e55 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -181,7 +181,7 @@ static irqreturn_t ad7923_trigger_handler(int irq, void *p) goto done; iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index ec0200dd52cb..54284766d2ef 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -212,7 +212,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) goto out; iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); out: iio_trigger_notify_done(indio_dev->trig); @@ -502,7 +502,7 @@ static irqreturn_t ad799x_event_handler(int irq, void *private) (i >> 1), IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } done: diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 8254f529b2a9..91636c0ba5b5 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -186,7 +186,7 @@ done: if (!sample_invalid) iio_push_to_buffers_with_timestamp(indio_dev, data, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index c73c6c62a6ac..c62bdb0a809e 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -400,7 +400,7 @@ static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val) iio_push_event(idev, IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, IIO_EV_TYPE_THRESH, dir), - iio_get_time_ns()); + iio_get_time_ns(idev)); } } diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 502f2fbe8aef..b95ce5d7ee2c 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -465,7 +465,7 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) s64 time_a, time_b; unsigned int alert; - time_a = iio_get_time_ns(); + time_a = iio_get_time_ns(indio_dev); /* * Because the timer thread and the chip conversion clock @@ -504,7 +504,7 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) data[i++] = val; } - time_b = iio_get_time_ns(); + time_b = iio_get_time_ns(indio_dev); iio_push_to_buffers_with_timestamp(indio_dev, (unsigned int *)data, time_a); @@ -554,7 +554,7 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev) dev_dbg(&indio_dev->dev, "Async readout mode: %d\n", chip->allow_async_readout); - chip->prev_ns = iio_get_time_ns(); + chip->prev_ns = iio_get_time_ns(indio_dev); chip->task = kthread_run(ina2xx_capture_thread, (void *)indio_dev, "%s:%d-%uus", indio_dev->name, indio_dev->id, diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 998dc3caad4c..73af30684657 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -788,7 +788,7 @@ static irqreturn_t max1363_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; struct max1363_state *st = iio_priv(indio_dev); - s64 timestamp = iio_get_time_ns(); + s64 timestamp = iio_get_time_ns(indio_dev); unsigned long mask, loc; u8 rx; u8 tx[2] = { st->setupbyte, @@ -1506,7 +1506,8 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) if (b_sent < 0) goto done_free; - iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, + iio_get_time_ns(indio_dev)); done_free: kfree(rxbuf); diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index f8807adc08c4..283d2a12b6da 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -139,7 +139,8 @@ static irqreturn_t adc081c_trigger_handler(int irq, void *p) if (ret < 0) goto out; buf[0] = ret; - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); out: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 8be192a84893..c9574af09882 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -288,7 +288,8 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) buf[0] = res; mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 653bf1379d2e..228a003adeed 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -594,7 +594,8 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id) if (iio_buffer_enabled(indio_dev)) { info->buffer[0] = info->value; iio_push_to_buffers_with_timestamp(indio_dev, - info->buffer, iio_get_time_ns()); + info->buffer, + iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); } else complete(&info->completion); diff --git a/drivers/iio/adc/xilinx-xadc-events.c b/drivers/iio/adc/xilinx-xadc-events.c index edcf3aabd70d..6d5c2a6f4e6e 100644 --- a/drivers/iio/adc/xilinx-xadc-events.c +++ b/drivers/iio/adc/xilinx-xadc-events.c @@ -46,7 +46,7 @@ static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event) iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } else { /* * For other channels we don't know whether it is a upper or @@ -56,7 +56,7 @@ static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event) iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } } diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c index 02e85db5d31f..ae038a59d256 100644 --- a/drivers/iio/chemical/atlas-ph-sensor.c +++ b/drivers/iio/chemical/atlas-ph-sensor.c @@ -343,7 +343,7 @@ static irqreturn_t atlas_trigger_handler(int irq, void *private) if (!ret) iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index 50afc0f8f16b..7c84e90d8ce8 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -62,7 +62,7 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p) if (sdata->hw_irq_trigger) timestamp = sdata->hw_timestamp; else - timestamp = iio_get_time_ns(); + timestamp = iio_get_time_ns(indio_dev); len = st_sensors_get_buffer_element(indio_dev, sdata->buffer_data); if (len < 0) diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c index 296e4ff19ae8..fab494d71951 100644 --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c @@ -29,7 +29,7 @@ irqreturn_t st_sensors_irq_handler(int irq, void *p) struct st_sensor_data *sdata = iio_priv(indio_dev); /* Get the time stamp as close in time as possible */ - sdata->hw_timestamp = iio_get_time_ns(); + sdata->hw_timestamp = iio_get_time_ns(indio_dev); return IRQ_WAKE_THREAD; } diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 968712be967f..559061ab1982 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -242,7 +242,7 @@ static irqreturn_t ad5421_fault_handler(int irq, void *data) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } if (events & AD5421_FAULT_UNDER_CURRENT) { @@ -251,7 +251,7 @@ static irqreturn_t ad5421_fault_handler(int irq, void *data) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } if (events & AD5421_FAULT_TEMP_OVER_140) { @@ -260,7 +260,7 @@ static irqreturn_t ad5421_fault_handler(int irq, void *data) 0, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } old_fault = fault; diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index 4e4c20d6d8b5..788b3d6fd1cc 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -223,7 +223,7 @@ static irqreturn_t ad5504_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns((struct iio_dev *)private)); return IRQ_HANDLED; } diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c index cf44a6f79431..b383892a5193 100644 --- a/drivers/iio/dummy/iio_simple_dummy_buffer.c +++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c @@ -85,7 +85,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) } } - iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_get_time_ns(indio_dev)); kfree(data); diff --git a/drivers/iio/dummy/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c index 6eb600ff7056..ed63ffd849f8 100644 --- a/drivers/iio/dummy/iio_simple_dummy_events.c +++ b/drivers/iio/dummy/iio_simple_dummy_events.c @@ -158,7 +158,7 @@ static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private) struct iio_dev *indio_dev = private; struct iio_dummy_state *st = iio_priv(indio_dev); - st->event_timestamp = iio_get_time_ns(); + st->event_timestamp = iio_get_time_ns(indio_dev); return IRQ_WAKE_THREAD; } diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 7ccc044063f6..8155251d9984 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -885,25 +885,25 @@ static irqreturn_t bmg160_event_handler(int irq, void *private) if (val & BMG160_ANY_MOTION_BIT_X) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, - 0, - IIO_MOD_X, - IIO_EV_TYPE_ROC, - dir), - iio_get_time_ns()); + 0, + IIO_MOD_X, + IIO_EV_TYPE_ROC, + dir), + iio_get_time_ns(indio_dev)); if (val & BMG160_ANY_MOTION_BIT_Y) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, - 0, - IIO_MOD_Y, - IIO_EV_TYPE_ROC, - dir), - iio_get_time_ns()); + 0, + IIO_MOD_Y, + IIO_EV_TYPE_ROC, + dir), + iio_get_time_ns(indio_dev)); if (val & BMG160_ANY_MOTION_BIT_Z) iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, - 0, - IIO_MOD_Z, - IIO_EV_TYPE_ROC, - dir), - iio_get_time_ns()); + 0, + IIO_MOD_Z, + IIO_EV_TYPE_ROC, + dir), + iio_get_time_ns(indio_dev)); ack_intr_status: if (!data->dready_trigger_on) { diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h index 359883525ab7..4c45488e3a7f 100644 --- a/drivers/iio/iio_core.h +++ b/drivers/iio/iio_core.h @@ -79,4 +79,7 @@ void iio_device_unregister_eventset(struct iio_dev *indio_dev); void iio_device_wakeup_eventset(struct iio_dev *indio_dev); int iio_event_getfd(struct iio_dev *indio_dev); +struct iio_event_interface; +bool iio_event_enabled(const struct iio_event_interface *ev_int); + #endif diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index 97928d558a15..e0251b8c1a52 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -411,7 +411,8 @@ static irqreturn_t bmi160_trigger_handler(int irq, void *p) buf[j++] = sample; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index d0700628ee6d..3a9f3eac91ab 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -107,7 +107,7 @@ irqreturn_t inv_mpu6050_irq_handler(int irq, void *p) struct inv_mpu6050_state *st = iio_priv(indio_dev); s64 timestamp; - timestamp = iio_get_time_ns(); + timestamp = iio_get_time_ns(indio_dev); kfifo_in_spinlocked(&st->timestamps, ×tamp, 1, &st->time_stamp_lock); diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 2a85bd888619..f914d5d140e4 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -178,6 +178,86 @@ ssize_t iio_read_const_attr(struct device *dev, } EXPORT_SYMBOL(iio_read_const_attr); +static int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id) +{ + int ret; + const struct iio_event_interface *ev_int = indio_dev->event_interface; + + ret = mutex_lock_interruptible(&indio_dev->mlock); + if (ret) + return ret; + if ((ev_int && iio_event_enabled(ev_int)) || + iio_buffer_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + indio_dev->clock_id = clock_id; + mutex_unlock(&indio_dev->mlock); + + return 0; +} + +/** + * iio_get_time_ns() - utility function to get a time stamp for events etc + * @indio_dev: device + */ +s64 iio_get_time_ns(const struct iio_dev *indio_dev) +{ + struct timespec tp; + + switch (iio_device_get_clock(indio_dev)) { + case CLOCK_REALTIME: + ktime_get_real_ts(&tp); + break; + case CLOCK_MONOTONIC: + ktime_get_ts(&tp); + break; + case CLOCK_MONOTONIC_RAW: + getrawmonotonic(&tp); + break; + case CLOCK_REALTIME_COARSE: + tp = current_kernel_time(); + break; + case CLOCK_MONOTONIC_COARSE: + tp = get_monotonic_coarse(); + break; + case CLOCK_BOOTTIME: + get_monotonic_boottime(&tp); + break; + case CLOCK_TAI: + timekeeping_clocktai(&tp); + break; + default: + BUG(); + } + + return timespec_to_ns(&tp); +} +EXPORT_SYMBOL(iio_get_time_ns); + +/** + * iio_get_time_res() - utility function to get time stamp clock resolution in + * nano seconds. + * @indio_dev: device + */ +unsigned int iio_get_time_res(const struct iio_dev *indio_dev) +{ + switch (iio_device_get_clock(indio_dev)) { + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: + case CLOCK_MONOTONIC_RAW: + case CLOCK_BOOTTIME: + case CLOCK_TAI: + return hrtimer_resolution; + case CLOCK_REALTIME_COARSE: + case CLOCK_MONOTONIC_COARSE: + return LOW_RES_NSEC; + default: + BUG(); + } +} +EXPORT_SYMBOL(iio_get_time_res); + static int __init iio_init(void) { int ret; @@ -990,11 +1070,91 @@ static ssize_t iio_show_dev_name(struct device *dev, static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL); +static ssize_t iio_show_timestamp_clock(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + const struct iio_dev *indio_dev = dev_to_iio_dev(dev); + const clockid_t clk = iio_device_get_clock(indio_dev); + const char *name; + ssize_t sz; + + switch (clk) { + case CLOCK_REALTIME: + name = "realtime\n"; + sz = sizeof("realtime\n"); + break; + case CLOCK_MONOTONIC: + name = "monotonic\n"; + sz = sizeof("monotonic\n"); + break; + case CLOCK_MONOTONIC_RAW: + name = "monotonic_raw\n"; + sz = sizeof("monotonic_raw\n"); + break; + case CLOCK_REALTIME_COARSE: + name = "realtime_coarse\n"; + sz = sizeof("realtime_coarse\n"); + break; + case CLOCK_MONOTONIC_COARSE: + name = "monotonic_coarse\n"; + sz = sizeof("monotonic_coarse\n"); + break; + case CLOCK_BOOTTIME: + name = "boottime\n"; + sz = sizeof("boottime\n"); + break; + case CLOCK_TAI: + name = "tai\n"; + sz = sizeof("tai\n"); + break; + default: + BUG(); + } + + memcpy(buf, name, sz); + return sz; +} + +static ssize_t iio_store_timestamp_clock(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + clockid_t clk; + int ret; + + if (sysfs_streq(buf, "realtime")) + clk = CLOCK_REALTIME; + else if (sysfs_streq(buf, "monotonic")) + clk = CLOCK_MONOTONIC; + else if (sysfs_streq(buf, "monotonic_raw")) + clk = CLOCK_MONOTONIC_RAW; + else if (sysfs_streq(buf, "realtime_coarse")) + clk = CLOCK_REALTIME_COARSE; + else if (sysfs_streq(buf, "monotonic_coarse")) + clk = CLOCK_MONOTONIC_COARSE; + else if (sysfs_streq(buf, "boottime")) + clk = CLOCK_BOOTTIME; + else if (sysfs_streq(buf, "tai")) + clk = CLOCK_TAI; + else + return -EINVAL; + + ret = iio_device_set_clock(dev_to_iio_dev(dev), clk); + if (ret) + return ret; + + return len; +} + +static DEVICE_ATTR(current_timestamp_clock, S_IRUGO | S_IWUSR, + iio_show_timestamp_clock, iio_store_timestamp_clock); + static int iio_device_register_sysfs(struct iio_dev *indio_dev) { int i, ret = 0, attrcount, attrn, attrcount_orig = 0; struct iio_dev_attr *p; - struct attribute **attr; + struct attribute **attr, *clk = NULL; /* First count elements in any existing group */ if (indio_dev->info->attrs) { @@ -1009,16 +1169,25 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) */ if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { - ret = iio_device_add_channel_sysfs(indio_dev, - &indio_dev - ->channels[i]); + const struct iio_chan_spec *chan = + &indio_dev->channels[i]; + + if (chan->type == IIO_TIMESTAMP) + clk = &dev_attr_current_timestamp_clock.attr; + + ret = iio_device_add_channel_sysfs(indio_dev, chan); if (ret < 0) goto error_clear_attrs; attrcount += ret; } + if (indio_dev->event_interface) + clk = &dev_attr_current_timestamp_clock.attr; + if (indio_dev->name) attrcount++; + if (clk) + attrcount++; indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1, sizeof(indio_dev->chan_attr_group.attrs[0]), @@ -1039,6 +1208,8 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr; if (indio_dev->name) indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr; + if (clk) + indio_dev->chan_attr_group.attrs[attrn++] = clk; indio_dev->groups[indio_dev->groupcounter++] = &indio_dev->chan_attr_group; diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index cae332b1d7ea..0ebfc923a997 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -44,6 +44,11 @@ struct iio_event_interface { struct mutex read_lock; }; +bool iio_event_enabled(const struct iio_event_interface *ev_int) +{ + return !!test_bit(IIO_BUSY_BIT_POS, &ev_int->flags); +} + /** * iio_push_event() - try to add event to the list for userspace reading * @indio_dev: IIO device structure @@ -60,7 +65,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) int copied; /* Does anyone care? */ - if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + if (iio_event_enabled(ev_int)) { ev.id = ev_code; ev.timestamp = timestamp; @@ -180,8 +185,14 @@ int iio_event_getfd(struct iio_dev *indio_dev) if (ev_int == NULL) return -ENODEV; - if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) - return -EBUSY; + fd = mutex_lock_interruptible(&indio_dev->mlock); + if (fd) + return fd; + + if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + fd = -EBUSY; + goto unlock; + } iio_device_get(indio_dev); @@ -194,6 +205,8 @@ int iio_event_getfd(struct iio_dev *indio_dev) kfifo_reset_out(&ev_int->det_events); } +unlock: + mutex_unlock(&indio_dev->mlock); return fd; } diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 98457f044aa5..7ad82fdd3e5b 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -289,7 +289,7 @@ static int iio_trigger_detach_poll_func(struct iio_trigger *trig, irqreturn_t iio_pollfunc_store_time(int irq, void *p) { struct iio_poll_func *pf = p; - pf->timestamp = iio_get_time_ns(); + pf->timestamp = iio_get_time_ns(pf->indio_dev); return IRQ_WAKE_THREAD; } EXPORT_SYMBOL(iio_pollfunc_store_time); diff --git a/drivers/iio/light/acpi-als.c b/drivers/iio/light/acpi-als.c index 53201d99a16c..f0b47c501f4e 100644 --- a/drivers/iio/light/acpi-als.c +++ b/drivers/iio/light/acpi-als.c @@ -118,7 +118,7 @@ static void acpi_als_notify(struct acpi_device *device, u32 event) struct iio_dev *indio_dev = acpi_driver_data(device); struct acpi_als *als = iio_priv(indio_dev); s32 *buffer = als->evt_buffer; - s64 time_ns = iio_get_time_ns(); + s64 time_ns = iio_get_time_ns(indio_dev); s32 val; int ret; diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 09ad5f1ce539..0113fc843a81 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -118,7 +118,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adjd_s311_data *data = iio_priv(indio_dev); - s64 time_ns = iio_get_time_ns(); + s64 time_ns = iio_get_time_ns(indio_dev); int i, j = 0; int ret = adjd_s311_req_data(indio_dev); diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index e1b9fa5a7e91..649b26f67813 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -396,7 +396,7 @@ static irqreturn_t apds9300_interrupt_handler(int irq, void *private) IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(dev_info)); apds9300_clear_intr(data); diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 651d57b8abbf..a4304edc3e0f 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -807,7 +807,7 @@ static irqreturn_t apds9960_interrupt_handler(int irq, void *private) IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); regmap_write(data->regmap, APDS9960_REG_CICLEAR, 1); } @@ -816,7 +816,7 @@ static irqreturn_t apds9960_interrupt_handler(int irq, void *private) IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); regmap_write(data->regmap, APDS9960_REG_PICLEAR, 1); } diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index c8d7b5ea7e78..9d66e89c57ef 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -268,7 +268,7 @@ static irqreturn_t cm36651_irq_handler(int irq, void *data) CM36651_CMD_READ_RAW_PROXIMITY, IIO_EV_TYPE_THRESH, ev_dir); - iio_push_event(indio_dev, ev_code, iio_get_time_ns()); + iio_push_event(indio_dev, ev_code, iio_get_time_ns(indio_dev)); return IRQ_HANDLED; } diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index af73af3586a9..6ada9149f142 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -851,7 +851,7 @@ static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data) GP2AP020A00F_SCAN_MODE_PROXIMITY, IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } else { iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE( @@ -859,7 +859,7 @@ static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data) GP2AP020A00F_SCAN_MODE_PROXIMITY, IIO_EV_TYPE_ROC, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } } @@ -925,7 +925,7 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data) IIO_MOD_LIGHT_CLEAR, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &priv->flags)) { @@ -939,7 +939,7 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data) IIO_MOD_LIGHT_CLEAR, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } } diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index a6b9d66233d5..f48b9e5bdb0e 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -188,7 +188,7 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p) } iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index e56937c40a18..f409c2047c05 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c @@ -267,7 +267,7 @@ static irqreturn_t lm3533_als_isr(int irq, void *dev_id) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); out: return IRQ_HANDLED; } diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index 6bf89d8f3741..3afc53a3d0b6 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -1256,7 +1256,8 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p) buf[j++] = psdata & LTR501_PS_DATA_MASK; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); @@ -1282,14 +1283,14 @@ static irqreturn_t ltr501_interrupt_handler(int irq, void *private) IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); if (status & LTR501_STATUS_PS_INTR) iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); return IRQ_HANDLED; } diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index f17cb2ea18f5..6511b20a2a29 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -511,7 +511,8 @@ static irqreturn_t max44000_trigger_handler(int irq, void *p) } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index b776c8ed4387..78c9b3a6453a 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -713,13 +713,13 @@ static irqreturn_t opt3001_irq(int irq, void *_iio) IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(iio)); if (ret & OPT3001_CONFIGURATION_FL) iio_push_event(iio, IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(iio)); } else if (ret & OPT3001_CONFIGURATION_CRF) { ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_RESULT); if (ret < 0) { diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 9e847f8f4f0c..45cf8b0a4363 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -528,7 +528,7 @@ static irqreturn_t stk3310_irq_handler(int irq, void *private) struct iio_dev *indio_dev = private; struct stk3310_data *data = iio_priv(indio_dev); - data->timestamp = iio_get_time_ns(); + data->timestamp = iio_get_time_ns(indio_dev); return IRQ_WAKE_THREAD; } diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index 8a15fb541dc3..a795afb7667b 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -216,7 +216,7 @@ static irqreturn_t tcs3414_trigger_handler(int irq, void *p) } iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index b29312f99077..3aa71e34ae28 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -202,7 +202,7 @@ static irqreturn_t tcs3472_trigger_handler(int irq, void *p) } iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 57b108c30e98..04598ae993d4 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -630,7 +630,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), - iio_get_time_ns()); + iio_get_time_ns(dev_info)); /* clear the interrupt and push the event */ i2c_smbus_write_byte(chip->client, TSL2563_CMD | TSL2563_CLEARINT); diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 45bc2f742f46..20c40f780964 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -833,7 +833,7 @@ static irqreturn_t us5182d_irq_thread_handler(int irq, void *private) dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING; ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir); - iio_push_event(indio_dev, ev, iio_get_time_ns()); + iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev)); ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret & ~US5182D_CFG0_PX_IRQ); diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 57d3654d7caf..2121b50ab9b3 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -829,7 +829,8 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev) buff[1] = clamp_t(s16, le16_to_cpu(buff[1]), -def->range, def->range); buff[2] = clamp_t(s16, le16_to_cpu(buff[2]), -def->range, def->range); - iio_push_to_buffers_with_timestamp(indio_dev, buff, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buff, + iio_get_time_ns(indio_dev)); return; unlock: diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index 77882b466e0f..ba3e2a374ee5 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -451,7 +451,7 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p) goto done; iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index 261d517428e4..f2be4a049056 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -261,7 +261,7 @@ static irqreturn_t mag3110_trigger_handler(int irq, void *p) } iio_push_to_buffers_with_timestamp(indio_dev, buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c index 01b2e0b18878..6392d7b62841 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -171,7 +171,7 @@ static irqreturn_t mpl3115_trigger_handler(int irq, void *p) mutex_unlock(&data->lock); iio_push_to_buffers_with_timestamp(indio_dev, buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c index 76578b07bb6e..feb41f82c64a 100644 --- a/drivers/iio/pressure/ms5611_core.c +++ b/drivers/iio/pressure/ms5611_core.c @@ -224,7 +224,8 @@ static irqreturn_t ms5611_trigger_handler(int irq, void *p) if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index c0b0e82abf94..3141c3c161bb 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -238,7 +238,7 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private) ret = lidar_get_measurement(data, data->buffer); if (!ret) { iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } else if (ret != -EINVAL) { dev_err(&data->client->dev, "cannot read LIDAR measurement"); } diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 66cd09a18786..1d74b3aafeed 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -492,7 +492,7 @@ static void sx9500_push_events(struct iio_dev *indio_dev) dir = new_prox ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan, IIO_EV_TYPE_THRESH, dir); - iio_push_event(indio_dev, ev, iio_get_time_ns()); + iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev)); data->prox_stat[chan] = new_prox; } } @@ -669,7 +669,7 @@ static irqreturn_t sx9500_trigger_handler(int irq, void *private) } iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); out: mutex_unlock(&data->mutex); diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 7a6fed3f2d3f..5c3410a74fdb 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -451,7 +451,7 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) struct iio_dev *indio_dev = private; u8 t; - s64 timestamp = iio_get_time_ns(); + s64 timestamp = iio_get_time_ns(indio_dev); lis3l02dq_spi_read_reg_8(indio_dev, LIS3L02DQ_REG_WAKE_UP_SRC_ADDR, diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 53c5425d02b3..aacf643e87d3 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -774,7 +774,7 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) struct iio_dev *indio_dev = private; struct sca3000_state *st = iio_priv(indio_dev); int ret, val; - s64 last_timestamp = iio_get_time_ns(); + s64 last_timestamp = iio_get_time_ns(indio_dev); /* * Could lead if badly timed to an extra read of status reg, diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index a06b46cb81ca..2177f1dd2b5d 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -705,7 +705,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) IIO_EV_DIR_RISING, IIO_EV_TYPE_THRESH, 0, 0, 0), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); else if (((channels[i] >> 11) & 0xFFF) <= st->cell_threshlow) iio_push_event(indio_dev, @@ -715,7 +715,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) IIO_EV_DIR_FALLING, IIO_EV_TYPE_THRESH, 0, 0, 0), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } else { if (((channels[i] >> 11) & 0xFFF) >= st->aux_threshhigh) iio_push_event(indio_dev, @@ -724,7 +724,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); else if (((channels[i] >> 11) & 0xFFF) <= st->aux_threshlow) iio_push_event(indio_dev, @@ -733,7 +733,7 @@ static irqreturn_t ad7280_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } } diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index a6f8eb11242c..0572df9aad85 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -77,7 +77,8 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) goto done; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns()); + iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_get_time_ns(indio_dev)); done: gpio_set_value(st->pdata->gpio_convst, 0); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index ac3735c7f4a9..5e8115b01011 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -253,7 +253,8 @@ static const struct attribute_group ad7816_attribute_group = { static irqreturn_t ad7816_event_handler(int irq, void *private) { - iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI, iio_get_time_ns()); + iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI, + iio_get_time_ns((struct iio_dev *)private)); return IRQ_HANDLED; } diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index a10e7d8e6002..3faffe59c933 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -1752,7 +1752,7 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) stat1 &= 0x1F; - time = iio_get_time_ns(); + time = iio_get_time_ns(indio_dev); if (stat1 & BIT(0)) iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, @@ -1804,7 +1804,7 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - iio_get_time_ns()); + iio_get_time_ns(indio_dev)); } return IRQ_HANDLED; diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index f6b9a10326ea..5578a077fcfb 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -493,7 +493,7 @@ static irqreturn_t ad7150_event_handler(int irq, void *private) struct iio_dev *indio_dev = private; struct ad7150_chip_info *chip = iio_priv(indio_dev); u8 int_status; - s64 timestamp = iio_get_time_ns(); + s64 timestamp = iio_get_time_ns(indio_dev); int ret; ret = i2c_smbus_read_byte_data(chip->client, AD7150_STATUS); diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index d553c8e18fcc..ea15bc1c300c 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1554,7 +1554,7 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; struct tsl2X7X_chip *chip = iio_priv(indio_dev); - s64 timestamp = iio_get_time_ns(); + s64 timestamp = iio_get_time_ns(indio_dev); int ret; u8 value; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 7c29cb0124ae..854e2dad1e0d 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -312,13 +312,8 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, }, \ } -/** - * iio_get_time_ns() - utility function to get a time stamp for events etc - **/ -static inline s64 iio_get_time_ns(void) -{ - return ktime_get_real_ns(); -} +s64 iio_get_time_ns(const struct iio_dev *indio_dev); +unsigned int iio_get_time_res(const struct iio_dev *indio_dev); /* Device operating modes */ #define INDIO_DIRECT_MODE 0x01 @@ -497,6 +492,7 @@ struct iio_buffer_setup_ops { * @chan_attr_group: [INTERN] group for all attrs in base directory * @name: [DRIVER] name of the device. * @info: [DRIVER] callbacks and constant info from driver + * @clock_id: [INTERN] timestamping clock posix identifier * @info_exist_lock: [INTERN] lock to prevent use during removal * @setup_ops: [DRIVER] callbacks to call before and after buffer * enable/disable @@ -537,6 +533,7 @@ struct iio_dev { struct attribute_group chan_attr_group; const char *name; const struct iio_info *info; + clockid_t clock_id; struct mutex info_exist_lock; const struct iio_buffer_setup_ops *setup_ops; struct cdev chrdev; @@ -565,7 +562,7 @@ extern struct bus_type iio_bus_type; /** * iio_device_put() - reference counted deallocation of struct device - * @indio_dev: IIO device structure containing the device + * @indio_dev: IIO device structure containing the device **/ static inline void iio_device_put(struct iio_dev *indio_dev) { @@ -573,6 +570,15 @@ static inline void iio_device_put(struct iio_dev *indio_dev) put_device(&indio_dev->dev); } +/** + * iio_device_get_clock() - Retrieve current timestamping clock for the device + * @indio_dev: IIO device structure containing the device + */ +static inline clockid_t iio_device_get_clock(const struct iio_dev *indio_dev) +{ + return indio_dev->clock_id; +} + /** * dev_to_iio_dev() - Get IIO device struct from a device struct * @dev: The device embedded in the IIO device -- cgit v1.3-14-g43fede From 0249a764485744b3f5babb02ced0fe6c199d89f7 Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Thu, 30 Jun 2016 14:00:22 +0200 Subject: doc-rst: flat-table directive - initial implementation Implements the reST flat-table directive. The ``flat-table`` is a double-stage list similar to the ``list-table`` with some additional features: * column-span: with the role ``cspan`` a cell can be extended through additional columns * row-span: with the role ``rspan`` a cell can be extended through additional rows * auto span rightmost cell of a table row over the missing cells on the right side of that table-row. With Option ``:fill-cells:`` this behavior can changed from *auto span* to *auto fill*, which automaticly inserts (empty) list tables The *list tables* formats are double stage lists. Compared to the ASCII-art they migth be less comfortable for readers of the text-files. Their advantage is, that they are easy to create/modify and that the diff of a modification is much more meaningfull, because it is limited to the modified content. The initial implementation was taken from the sphkerneldoc project [1] [1] https://github.com/return42/sphkerneldoc/commits/master/scripts/site-python/linuxdoc/rstFlatTable.py Signed-off-by: Markus Heiser [jc: fixed typos and misspellings in the docs] Signed-off-by: Jonathan Corbet --- Documentation/conf.py | 2 +- Documentation/kernel-documentation.rst | 86 ++++++++ Documentation/sphinx/rstFlatTable.py | 365 +++++++++++++++++++++++++++++++++ 3 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 Documentation/sphinx/rstFlatTable.py (limited to 'Documentation') diff --git a/Documentation/conf.py b/Documentation/conf.py index 6cc41a0555a3..792b6338ef19 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -28,7 +28,7 @@ sys.path.insert(0, os.path.abspath('sphinx')) # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['kernel-doc'] +extensions = ['kernel-doc', 'rstFlatTable'] # Gracefully handle missing rst2pdf. try: diff --git a/Documentation/kernel-documentation.rst b/Documentation/kernel-documentation.rst index ad3506c13b11..391decc66a18 100644 --- a/Documentation/kernel-documentation.rst +++ b/Documentation/kernel-documentation.rst @@ -107,6 +107,92 @@ Here are some specific guidelines for the kernel documentation: the order as encountered."), having the higher levels the same overall makes it easier to follow the documents. +list tables +----------- + +We recommend the use of *list table* formats. The *list table* formats are +double-stage lists. Compared to the ASCII-art they might not be as +comfortable for +readers of the text files. Their advantage is that they are easy to +create or modify and that the diff of a modification is much more meaningful, +because it is limited to the modified content. + +The ``flat-table`` is a double-stage list similar to the ``list-table`` with +some additional features: + +* column-span: with the role ``cspan`` a cell can be extended through + additional columns + +* row-span: with the role ``rspan`` a cell can be extended through + additional rows + +* auto span rightmost cell of a table row over the missing cells on the right + side of that table-row. With Option ``:fill-cells:`` this behavior can + changed from *auto span* to *auto fill*, which automatically inserts (empty) + cells instead of spanning the last cell. + +options: + +* ``:header-rows:`` [int] count of header rows +* ``:stub-columns:`` [int] count of stub columns +* ``:widths:`` [[int] [int] ... ] widths of columns +* ``:fill-cells:`` instead of auto-spanning missing cells, insert missing cells + +roles: + +* ``:cspan:`` [int] additional columns (*morecols*) +* ``:rspan:`` [int] additional rows (*morerows*) + +The example below shows how to use this markup. The first level of the staged +list is the *table-row*. In the *table-row* there is only one markup allowed, +the list of the cells in this *table-row*. Exceptions are *comments* ( ``..`` ) +and *targets* (e.g. a ref to ``:ref:`last row ``` / :ref:`last row +`). + +.. code-block:: rst + + .. flat-table:: table title + :widths: 2 1 1 3 + + * - head col 1 + - head col 2 + - head col 3 + - head col 4 + + * - column 1 + - field 1.1 + - field 1.2 with autospan + + * - column 2 + - field 2.1 + - :rspan:`1` :cspan:`1` field 2.2 - 3.3 + + * .. _`last row`: + + - column 3 + +Rendered as: + + .. flat-table:: table title + :widths: 2 1 1 3 + + * - head col 1 + - head col 2 + - head col 3 + - head col 4 + + * - column 1 + - field 1.1 + - field 1.2 with autospan + + * - column 2 + - field 2.1 + - :rspan:`1` :cspan:`1` field 2.2 - 3.3 + + * .. _`last row`: + + - column 3 + Including kernel-doc comments ============================= diff --git a/Documentation/sphinx/rstFlatTable.py b/Documentation/sphinx/rstFlatTable.py new file mode 100644 index 000000000000..26db852e3c74 --- /dev/null +++ b/Documentation/sphinx/rstFlatTable.py @@ -0,0 +1,365 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8; mode: python -*- +# pylint: disable=C0330, R0903, R0912 + +u""" + flat-table + ~~~~~~~~~~ + + Implementation of the ``flat-table`` reST-directive. + + :copyright: Copyright (C) 2016 Markus Heiser + :license: GPL Version 2, June 1991 see linux/COPYING for details. + + The ``flat-table`` (:py:class:`FlatTable`) is a double-stage list similar to + the ``list-table`` with some additional features: + + * *column-span*: with the role ``cspan`` a cell can be extended through + additional columns + + * *row-span*: with the role ``rspan`` a cell can be extended through + additional rows + + * *auto span* rightmost cell of a table row over the missing cells on the + right side of that table-row. With Option ``:fill-cells:`` this behavior + can changed from *auto span* to *auto fill*, which automaticly inserts + (empty) cells instead of spanning the last cell. + + Options: + + * header-rows: [int] count of header rows + * stub-columns: [int] count of stub columns + * widths: [[int] [int] ... ] widths of columns + * fill-cells: instead of autospann missing cells, insert missing cells + + roles: + + * cspan: [int] additionale columns (*morecols*) + * rspan: [int] additionale rows (*morerows*) +""" + +# ============================================================================== +# imports +# ============================================================================== + +import sys + +from docutils import nodes +from docutils.parsers.rst import directives, roles +from docutils.parsers.rst.directives.tables import Table +from docutils.utils import SystemMessagePropagation + +# ============================================================================== +# common globals +# ============================================================================== + +# The version numbering follows numbering of the specification +# (Documentation/books/kernel-doc-HOWTO). +__version__ = '1.0' + +PY3 = sys.version_info[0] == 3 +PY2 = sys.version_info[0] == 2 + +if PY3: + # pylint: disable=C0103, W0622 + unicode = str + basestring = str + +# ============================================================================== +def setup(app): +# ============================================================================== + + app.add_directive("flat-table", FlatTable) + roles.register_local_role('cspan', c_span) + roles.register_local_role('rspan', r_span) + +# ============================================================================== +def c_span(name, rawtext, text, lineno, inliner, options=None, content=None): +# ============================================================================== + # pylint: disable=W0613 + + options = options if options is not None else {} + content = content if content is not None else [] + nodelist = [colSpan(span=int(text))] + msglist = [] + return nodelist, msglist + +# ============================================================================== +def r_span(name, rawtext, text, lineno, inliner, options=None, content=None): +# ============================================================================== + # pylint: disable=W0613 + + options = options if options is not None else {} + content = content if content is not None else [] + nodelist = [rowSpan(span=int(text))] + msglist = [] + return nodelist, msglist + + +# ============================================================================== +class rowSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321 +class colSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321 +# ============================================================================== + +# ============================================================================== +class FlatTable(Table): +# ============================================================================== + + u"""FlatTable (``flat-table``) directive""" + + option_spec = { + 'name': directives.unchanged + , 'class': directives.class_option + , 'header-rows': directives.nonnegative_int + , 'stub-columns': directives.nonnegative_int + , 'widths': directives.positive_int_list + , 'fill-cells' : directives.flag } + + def run(self): + + if not self.content: + error = self.state_machine.reporter.error( + 'The "%s" directive is empty; content required.' % self.name, + nodes.literal_block(self.block_text, self.block_text), + line=self.lineno) + return [error] + + title, messages = self.make_title() + node = nodes.Element() # anonymous container for parsing + self.state.nested_parse(self.content, self.content_offset, node) + + tableBuilder = ListTableBuilder(self) + tableBuilder.parseFlatTableNode(node) + tableNode = tableBuilder.buildTableNode() + # SDK.CONSOLE() # print --> tableNode.asdom().toprettyxml() + if title: + tableNode.insert(0, title) + return [tableNode] + messages + + +# ============================================================================== +class ListTableBuilder(object): +# ============================================================================== + + u"""Builds a table from a double-stage list""" + + def __init__(self, directive): + self.directive = directive + self.rows = [] + self.max_cols = 0 + + def buildTableNode(self): + + colwidths = self.directive.get_column_widths(self.max_cols) + stub_columns = self.directive.options.get('stub-columns', 0) + header_rows = self.directive.options.get('header-rows', 0) + + table = nodes.table() + tgroup = nodes.tgroup(cols=len(colwidths)) + table += tgroup + + + for colwidth in colwidths: + colspec = nodes.colspec(colwidth=colwidth) + # FIXME: It seems, that the stub method only works well in the + # absence of rowspan (observed by the html buidler, the docutils-xml + # build seems OK). This is not extraordinary, because there exists + # no table directive (except *this* flat-table) which allows to + # define coexistent of rowspan and stubs (there was no use-case + # before flat-table). This should be reviewed (later). + if stub_columns: + colspec.attributes['stub'] = 1 + stub_columns -= 1 + tgroup += colspec + stub_columns = self.directive.options.get('stub-columns', 0) + + if header_rows: + thead = nodes.thead() + tgroup += thead + for row in self.rows[:header_rows]: + thead += self.buildTableRowNode(row) + + tbody = nodes.tbody() + tgroup += tbody + + for row in self.rows[header_rows:]: + tbody += self.buildTableRowNode(row) + return table + + def buildTableRowNode(self, row_data, classes=None): + classes = [] if classes is None else classes + row = nodes.row() + for cell in row_data: + if cell is None: + continue + cspan, rspan, cellElements = cell + + attributes = {"classes" : classes} + if rspan: + attributes['morerows'] = rspan + if cspan: + attributes['morecols'] = cspan + entry = nodes.entry(**attributes) + entry.extend(cellElements) + row += entry + return row + + def raiseError(self, msg): + error = self.directive.state_machine.reporter.error( + msg + , nodes.literal_block(self.directive.block_text + , self.directive.block_text) + , line = self.directive.lineno ) + raise SystemMessagePropagation(error) + + def parseFlatTableNode(self, node): + u"""parses the node from a :py:class:`FlatTable` directive's body""" + + if len(node) != 1 or not isinstance(node[0], nodes.bullet_list): + self.raiseError( + 'Error parsing content block for the "%s" directive: ' + 'exactly one bullet list expected.' % self.directive.name ) + + for rowNum, rowItem in enumerate(node[0]): + row = self.parseRowItem(rowItem, rowNum) + self.rows.append(row) + self.roundOffTableDefinition() + + def roundOffTableDefinition(self): + u"""Round off the table definition. + + This method rounds off the table definition in :py:member:`rows`. + + * This method inserts the needed ``None`` values for the missing cells + arising from spanning cells over rows and/or columns. + + * recount the :py:member:`max_cols` + + * Autospan or fill (option ``fill-cells``) missing cells on the right + side of the table-row + """ + + y = 0 + while y < len(self.rows): + x = 0 + + while x < len(self.rows[y]): + cell = self.rows[y][x] + if cell is None: + x += 1 + continue + cspan, rspan = cell[:2] + # handle colspan in current row + for c in range(cspan): + try: + self.rows[y].insert(x+c+1, None) + except: # pylint: disable=W0702 + # the user sets ambiguous rowspans + pass # SDK.CONSOLE() + # handle colspan in spanned rows + for r in range(rspan): + for c in range(cspan + 1): + try: + self.rows[y+r+1].insert(x+c, None) + except: # pylint: disable=W0702 + # the user sets ambiguous rowspans + pass # SDK.CONSOLE() + x += 1 + y += 1 + + # Insert the missing cells on the right side. For this, first + # re-calculate the max columns. + + for row in self.rows: + if self.max_cols < len(row): + self.max_cols = len(row) + + # fill with empty cells or cellspan? + + fill_cells = False + if 'fill-cells' in self.directive.options: + fill_cells = True + + for row in self.rows: + x = self.max_cols - len(row) + if x and not fill_cells: + if row[-1] is None: + row.append( ( x - 1, 0, []) ) + else: + cspan, rspan, content = row[-1] + row[-1] = (cspan + x, rspan, content) + elif x and fill_cells: + for i in range(x): + row.append( (0, 0, nodes.comment()) ) + + def pprint(self): + # for debugging + retVal = "[ " + for row in self.rows: + retVal += "[ " + for col in row: + if col is None: + retVal += ('%r' % col) + retVal += "\n , " + else: + content = col[2][0].astext() + if len (content) > 30: + content = content[:30] + "..." + retVal += ('(cspan=%s, rspan=%s, %r)' + % (col[0], col[1], content)) + retVal += "]\n , " + retVal = retVal[:-2] + retVal += "]\n , " + retVal = retVal[:-2] + return retVal + "]" + + def parseRowItem(self, rowItem, rowNum): + row = [] + childNo = 0 + error = False + cell = None + target = None + + for child in rowItem: + if (isinstance(child , nodes.comment) + or isinstance(child, nodes.system_message)): + pass + elif isinstance(child , nodes.target): + target = child + elif isinstance(child, nodes.bullet_list): + childNo += 1 + cell = child + else: + error = True + break + + if childNo != 1 or error: + self.raiseError( + 'Error parsing content block for the "%s" directive: ' + 'two-level bullet list expected, but row %s does not ' + 'contain a second-level bullet list.' + % (self.directive.name, rowNum + 1)) + + for cellItem in cell: + cspan, rspan, cellElements = self.parseCellItem(cellItem) + if target is not None: + cellElements.insert(0, target) + row.append( (cspan, rspan, cellElements) ) + return row + + def parseCellItem(self, cellItem): + # search and remove cspan, rspan colspec from the first element in + # this listItem (field). + cspan = rspan = 0 + if not len(cellItem): + return cspan, rspan, [] + for elem in cellItem[0]: + if isinstance(elem, colSpan): + cspan = elem.get("span") + elem.parent.remove(elem) + continue + if isinstance(elem, rowSpan): + rspan = elem.get("span") + elem.parent.remove(elem) + continue + return cspan, rspan, cellItem[:] -- cgit v1.3-14-g43fede From 05d0066a5787189bb31a5808c1e9b3157561c184 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 29 Jun 2016 18:05:56 +0900 Subject: Doc: PM: Fix a typo in intel_powerclamp.txt This patch fix a spelling typo in intel_powerclamp.txt Signed-off-by: Masanari Iida Signed-off-by: Jonathan Corbet --- Documentation/thermal/intel_powerclamp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/thermal/intel_powerclamp.txt b/Documentation/thermal/intel_powerclamp.txt index 332de4a39b5a..60073dc9f748 100644 --- a/Documentation/thermal/intel_powerclamp.txt +++ b/Documentation/thermal/intel_powerclamp.txt @@ -121,7 +121,7 @@ time is considered largely as a non-causal system where its behavior cannot be based on the past or current input. Therefore, the intel_powerclamp driver attempts to enforce the desired idle time instantly as given input (target idle ratio). After injection, -powerclamp moniors the actual idle for a given time window and adjust +powerclamp monitors the actual idle for a given time window and adjust the next injection accordingly to avoid over/under correction. When used in a causal control system, such as a temperature control, -- cgit v1.3-14-g43fede From 19abdb15f3c781565f375db2e13d6c9f8bcbb561 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 30 Jun 2016 13:07:33 -0600 Subject: Add .pyc files to .gitignore Signed-off-by: Jonathan Corbet --- Documentation/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/.gitignore b/Documentation/.gitignore index 53752db253e3..e74fec8693b2 100644 --- a/Documentation/.gitignore +++ b/Documentation/.gitignore @@ -1 +1,2 @@ output +*.pyc -- cgit v1.3-14-g43fede From 5377d91f3e88d5c8da46b1feba78b00d379fb7b6 Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Thu, 30 Jun 2016 15:18:56 +0200 Subject: doc-rst: linux_tv DocBook to reST migration (docs-next) This is the restructuredText (reST) migration of the ``media`` DocBook-XML set from the linux_tv project. Signed-off-by: Markus Heiser Signed-off-by: Mauro Carvalho Chehab --- Documentation/index.rst | 1 + Documentation/linux_tv/audio.h.rst | 153 + Documentation/linux_tv/ca.h.rst | 108 + Documentation/linux_tv/conf.py | 221 + Documentation/linux_tv/dmx.h.rst | 173 + Documentation/linux_tv/frontend.h.rst | 620 + Documentation/linux_tv/index.rst | 100 + .../media/dvb/FE_DISHNETWORK_SEND_LEGACY_CMD.rst | 55 + Documentation/linux_tv/media/dvb/FE_GET_EVENT.rst | 89 + .../linux_tv/media/dvb/FE_GET_FRONTEND.rst | 77 + Documentation/linux_tv/media/dvb/FE_READ_BER.rst | 61 + .../linux_tv/media/dvb/FE_READ_SIGNAL_STRENGTH.rst | 64 + Documentation/linux_tv/media/dvb/FE_READ_SNR.rst | 61 + .../media/dvb/FE_READ_UNCORRECTED_BLOCKS.rst | 66 + .../linux_tv/media/dvb/FE_SET_FRONTEND.rst | 84 + Documentation/linux_tv/media/dvb/audio.rst | 37 + .../linux_tv/media/dvb/audio_data_types.rst | 187 + .../linux_tv/media/dvb/audio_function_calls.rst | 1308 +++ Documentation/linux_tv/media/dvb/audio_h.rst | 24 + Documentation/linux_tv/media/dvb/ca.rst | 29 + Documentation/linux_tv/media/dvb/ca_data_types.rst | 121 + .../linux_tv/media/dvb/ca_function_calls.rst | 541 + Documentation/linux_tv/media/dvb/ca_h.rst | 24 + Documentation/linux_tv/media/dvb/demux.rst | 29 + Documentation/linux_tv/media/dvb/dmx_fcalls.rst | 1013 ++ Documentation/linux_tv/media/dvb/dmx_h.rst | 24 + Documentation/linux_tv/media/dvb/dmx_types.rst | 253 + Documentation/linux_tv/media/dvb/dtv-fe-stats.rst | 28 + .../linux_tv/media/dvb/dtv-properties.rst | 26 + Documentation/linux_tv/media/dvb/dtv-property.rst | 42 + Documentation/linux_tv/media/dvb/dtv-stats.rst | 29 + .../linux_tv/media/dvb/dvb-fe-read-status.rst | 31 + .../linux_tv/media/dvb/dvb-frontend-event.rst | 26 + .../linux_tv/media/dvb/dvb-frontend-parameters.rst | 130 + Documentation/linux_tv/media/dvb/dvbapi.rst | 95 + .../linux_tv/media/dvb/dvbproperty-006.rst | 21 + Documentation/linux_tv/media/dvb/dvbproperty.rst | 122 + Documentation/linux_tv/media/dvb/examples.rst | 391 + .../linux_tv/media/dvb/fe-bandwidth-t.rst | 88 + .../media/dvb/fe-diseqc-recv-slave-reply.rst | 88 + .../media/dvb/fe-diseqc-reset-overload.rst | 51 + .../linux_tv/media/dvb/fe-diseqc-send-burst.rst | 93 + .../media/dvb/fe-diseqc-send-master-cmd.rst | 78 + .../media/dvb/fe-enable-high-lnb-voltage.rst | 58 + Documentation/linux_tv/media/dvb/fe-get-info.rst | 434 + .../linux_tv/media/dvb/fe-get-property.rst | 75 + .../linux_tv/media/dvb/fe-read-status.rst | 143 + .../media/dvb/fe-set-frontend-tune-mode.rst | 60 + Documentation/linux_tv/media/dvb/fe-set-tone.rst | 100 + .../linux_tv/media/dvb/fe-set-voltage.rst | 68 + Documentation/linux_tv/media/dvb/fe-type-t.rst | 100 + .../linux_tv/media/dvb/fe_property_parameters.rst | 1976 ++++ .../media/dvb/frontend-property-cable-systems.rst | 84 + .../dvb/frontend-property-satellite-systems.rst | 112 + .../dvb/frontend-property-terrestrial-systems.rst | 303 + .../media/dvb/frontend-stat-properties.rst | 254 + Documentation/linux_tv/media/dvb/frontend.rst | 62 + .../linux_tv/media/dvb/frontend_f_close.rst | 55 + .../linux_tv/media/dvb/frontend_f_open.rst | 108 + .../linux_tv/media/dvb/frontend_fcalls.rst | 35 + Documentation/linux_tv/media/dvb/frontend_h.rst | 24 + .../linux_tv/media/dvb/frontend_legacy_api.rst | 49 + .../media/dvb/frontend_legacy_dvbv3_api.rst | 29 + Documentation/linux_tv/media/dvb/intro.rst | 204 + .../linux_tv/media/dvb/intro_files/dvbstb.pdf | Bin 0 -> 1881 bytes .../linux_tv/media/dvb/intro_files/dvbstb.png | Bin 0 -> 22655 bytes .../linux_tv/media/dvb/legacy_dvb_apis.rst | 31 + Documentation/linux_tv/media/dvb/net.rst | 219 + Documentation/linux_tv/media/dvb/net_h.rst | 24 + .../linux_tv/media/dvb/query-dvb-frontend-info.rst | 22 + Documentation/linux_tv/media/dvb/video.rst | 46 + .../linux_tv/media/dvb/video_function_calls.rst | 1880 +++ Documentation/linux_tv/media/dvb/video_h.rst | 24 + Documentation/linux_tv/media/dvb/video_types.rst | 390 + .../media/v4l/Remote_controllers_Intro.rst | 33 + .../media/v4l/Remote_controllers_table_change.rst | 29 + .../media/v4l/Remote_controllers_tables.rst | 768 ++ Documentation/linux_tv/media/v4l/app-pri.rst | 39 + Documentation/linux_tv/media/v4l/async.rst | 18 + Documentation/linux_tv/media/v4l/audio.rst | 97 + Documentation/linux_tv/media/v4l/biblio.rst | 390 + Documentation/linux_tv/media/v4l/buffer.rst | 966 ++ .../linux_tv/media/v4l/capture-example.rst | 24 + Documentation/linux_tv/media/v4l/capture.c.rst | 675 ++ Documentation/linux_tv/media/v4l/colorspaces.rst | 172 + Documentation/linux_tv/media/v4l/common-defs.rst | 24 + Documentation/linux_tv/media/v4l/common.rst | 56 + Documentation/linux_tv/media/v4l/compat.rst | 29 + Documentation/linux_tv/media/v4l/control.rst | 536 + Documentation/linux_tv/media/v4l/controls.rst | 18 + Documentation/linux_tv/media/v4l/crop.rst | 300 + .../linux_tv/media/v4l/crop_files/crop.gif | Bin 0 -> 5967 bytes .../linux_tv/media/v4l/crop_files/crop.pdf | Bin 0 -> 5846 bytes Documentation/linux_tv/media/v4l/depth-formats.rst | 26 + Documentation/linux_tv/media/v4l/dev-capture.rst | 111 + Documentation/linux_tv/media/v4l/dev-codec.rst | 41 + Documentation/linux_tv/media/v4l/dev-effect.rst | 31 + Documentation/linux_tv/media/v4l/dev-event.rst | 56 + Documentation/linux_tv/media/v4l/dev-osd.rst | 154 + Documentation/linux_tv/media/v4l/dev-output.rst | 108 + Documentation/linux_tv/media/v4l/dev-overlay.rst | 328 + Documentation/linux_tv/media/v4l/dev-radio.rst | 61 + Documentation/linux_tv/media/v4l/dev-raw-vbi.rst | 368 + .../media/v4l/dev-raw-vbi_files/vbi_525.gif | Bin 0 -> 4741 bytes .../media/v4l/dev-raw-vbi_files/vbi_525.pdf | Bin 0 -> 3395 bytes .../media/v4l/dev-raw-vbi_files/vbi_625.gif | Bin 0 -> 5095 bytes .../media/v4l/dev-raw-vbi_files/vbi_625.pdf | Bin 0 -> 3683 bytes .../media/v4l/dev-raw-vbi_files/vbi_hsync.gif | Bin 0 -> 2400 bytes .../media/v4l/dev-raw-vbi_files/vbi_hsync.pdf | Bin 0 -> 7405 bytes Documentation/linux_tv/media/v4l/dev-rds.rst | 266 + Documentation/linux_tv/media/v4l/dev-sdr.rst | 129 + .../linux_tv/media/v4l/dev-sliced-vbi.rst | 804 ++ Documentation/linux_tv/media/v4l/dev-subdev.rst | 502 + .../media/v4l/dev-subdev_files/pipeline.pdf | Bin 0 -> 20276 bytes .../media/v4l/dev-subdev_files/pipeline.png | Bin 0 -> 12130 bytes .../subdev-image-processing-crop.pdf | Bin 0 -> 20729 bytes .../subdev-image-processing-crop.svg | 63 + .../subdev-image-processing-full.pdf | Bin 0 -> 46311 bytes .../subdev-image-processing-full.svg | 163 + ...ubdev-image-processing-scaling-multi-source.pdf | Bin 0 -> 36714 bytes ...ubdev-image-processing-scaling-multi-source.svg | 116 + Documentation/linux_tv/media/v4l/dev-teletext.rst | 43 + Documentation/linux_tv/media/v4l/devices.rst | 37 + Documentation/linux_tv/media/v4l/diff-v4l.rst | 963 ++ Documentation/linux_tv/media/v4l/dmabuf.rst | 158 + Documentation/linux_tv/media/v4l/driver.rst | 18 + Documentation/linux_tv/media/v4l/dv-timings.rst | 47 + .../linux_tv/media/v4l/extended-controls.rst | 4533 +++++++ Documentation/linux_tv/media/v4l/fdl-appendix.rst | 487 + Documentation/linux_tv/media/v4l/field-order.rst | 210 + .../media/v4l/field-order_files/fieldseq_bt.gif | Bin 0 -> 25430 bytes .../media/v4l/field-order_files/fieldseq_bt.pdf | Bin 0 -> 9185 bytes .../media/v4l/field-order_files/fieldseq_tb.gif | Bin 0 -> 25323 bytes .../media/v4l/field-order_files/fieldseq_tb.pdf | Bin 0 -> 9173 bytes Documentation/linux_tv/media/v4l/format.rst | 101 + Documentation/linux_tv/media/v4l/func-close.rst | 56 + Documentation/linux_tv/media/v4l/func-ioctl.rst | 69 + Documentation/linux_tv/media/v4l/func-mmap.rst | 141 + Documentation/linux_tv/media/v4l/func-munmap.rst | 65 + Documentation/linux_tv/media/v4l/func-open.rst | 90 + Documentation/linux_tv/media/v4l/func-poll.rst | 118 + Documentation/linux_tv/media/v4l/func-read.rst | 138 + Documentation/linux_tv/media/v4l/func-select.rst | 108 + Documentation/linux_tv/media/v4l/func-write.rst | 89 + Documentation/linux_tv/media/v4l/gen-errors.rst | 109 + Documentation/linux_tv/media/v4l/hist-v4l2.rst | 1490 +++ Documentation/linux_tv/media/v4l/io.rst | 62 + Documentation/linux_tv/media/v4l/keytable.c.rst | 187 + .../linux_tv/media/v4l/libv4l-introduction.rst | 178 + Documentation/linux_tv/media/v4l/libv4l.rst | 24 + .../linux_tv/media/v4l/lirc_dev_intro.rst | 37 + .../linux_tv/media/v4l/lirc_device_interface.rst | 26 + Documentation/linux_tv/media/v4l/lirc_ioctl.rst | 165 + Documentation/linux_tv/media/v4l/lirc_read.rst | 28 + Documentation/linux_tv/media/v4l/lirc_write.rst | 23 + .../linux_tv/media/v4l/media-controller-intro.rst | 42 + .../linux_tv/media/v4l/media-controller-model.rst | 44 + .../linux_tv/media/v4l/media-controller.rst | 66 + .../linux_tv/media/v4l/media-func-close.rst | 54 + .../linux_tv/media/v4l/media-func-ioctl.rst | 74 + .../linux_tv/media/v4l/media-func-open.rst | 76 + .../linux_tv/media/v4l/media-ioc-device-info.rst | 149 + .../linux_tv/media/v4l/media-ioc-enum-entities.rst | 204 + .../linux_tv/media/v4l/media-ioc-enum-links.rst | 180 + .../linux_tv/media/v4l/media-ioc-g-topology.rst | 436 + .../linux_tv/media/v4l/media-ioc-setup-link.rst | 75 + Documentation/linux_tv/media/v4l/media-types.rst | 433 + Documentation/linux_tv/media/v4l/mmap.rst | 286 + Documentation/linux_tv/media/v4l/open.rst | 168 + Documentation/linux_tv/media/v4l/pixfmt-002.rst | 207 + Documentation/linux_tv/media/v4l/pixfmt-003.rst | 177 + Documentation/linux_tv/media/v4l/pixfmt-004.rst | 60 + Documentation/linux_tv/media/v4l/pixfmt-006.rst | 291 + Documentation/linux_tv/media/v4l/pixfmt-007.rst | 870 ++ Documentation/linux_tv/media/v4l/pixfmt-008.rst | 41 + Documentation/linux_tv/media/v4l/pixfmt-013.rst | 140 + Documentation/linux_tv/media/v4l/pixfmt-grey.rst | 89 + .../linux_tv/media/v4l/pixfmt-indexed.rst | 84 + Documentation/linux_tv/media/v4l/pixfmt-m420.rst | 238 + Documentation/linux_tv/media/v4l/pixfmt-nv12.rst | 241 + Documentation/linux_tv/media/v4l/pixfmt-nv12m.rst | 256 + Documentation/linux_tv/media/v4l/pixfmt-nv12mt.rst | 71 + .../media/v4l/pixfmt-nv12mt_files/nv12mt.gif | Bin 0 -> 2108 bytes .../v4l/pixfmt-nv12mt_files/nv12mt_example.gif | Bin 0 -> 6858 bytes Documentation/linux_tv/media/v4l/pixfmt-nv16.rst | 290 + Documentation/linux_tv/media/v4l/pixfmt-nv16m.rst | 297 + Documentation/linux_tv/media/v4l/pixfmt-nv24.rst | 182 + .../linux_tv/media/v4l/pixfmt-packed-rgb.rst | 1479 +++ .../linux_tv/media/v4l/pixfmt-packed-yuv.rst | 325 + .../linux_tv/media/v4l/pixfmt-reserved.rst | 371 + Documentation/linux_tv/media/v4l/pixfmt-rgb.rst | 34 + .../linux_tv/media/v4l/pixfmt-sbggr16.rst | 125 + Documentation/linux_tv/media/v4l/pixfmt-sbggr8.rst | 93 + .../linux_tv/media/v4l/pixfmt-sdr-cs08.rst | 55 + .../linux_tv/media/v4l/pixfmt-sdr-cs14le.rst | 60 + .../linux_tv/media/v4l/pixfmt-sdr-cu08.rst | 55 + .../linux_tv/media/v4l/pixfmt-sdr-cu16le.rst | 59 + .../linux_tv/media/v4l/pixfmt-sdr-ru12le.rst | 50 + Documentation/linux_tv/media/v4l/pixfmt-sgbrg8.rst | 93 + Documentation/linux_tv/media/v4l/pixfmt-sgrbg8.rst | 93 + .../linux_tv/media/v4l/pixfmt-srggb10.rst | 129 + .../linux_tv/media/v4l/pixfmt-srggb10alaw8.rst | 32 + .../linux_tv/media/v4l/pixfmt-srggb10dpcm8.rst | 33 + .../linux_tv/media/v4l/pixfmt-srggb10p.rst | 112 + .../linux_tv/media/v4l/pixfmt-srggb12.rst | 129 + Documentation/linux_tv/media/v4l/pixfmt-srggb8.rst | 93 + Documentation/linux_tv/media/v4l/pixfmt-uv8.rst | 88 + Documentation/linux_tv/media/v4l/pixfmt-uyvy.rst | 216 + Documentation/linux_tv/media/v4l/pixfmt-vyuy.rst | 216 + Documentation/linux_tv/media/v4l/pixfmt-y10.rst | 122 + Documentation/linux_tv/media/v4l/pixfmt-y10b.rst | 56 + Documentation/linux_tv/media/v4l/pixfmt-y12.rst | 122 + Documentation/linux_tv/media/v4l/pixfmt-y12i.rst | 59 + Documentation/linux_tv/media/v4l/pixfmt-y16-be.rst | 123 + Documentation/linux_tv/media/v4l/pixfmt-y16.rst | 123 + Documentation/linux_tv/media/v4l/pixfmt-y41p.rst | 313 + Documentation/linux_tv/media/v4l/pixfmt-y8i.rst | 123 + Documentation/linux_tv/media/v4l/pixfmt-yuv410.rst | 219 + .../linux_tv/media/v4l/pixfmt-yuv411p.rst | 237 + Documentation/linux_tv/media/v4l/pixfmt-yuv420.rst | 250 + .../linux_tv/media/v4l/pixfmt-yuv420m.rst | 265 + .../linux_tv/media/v4l/pixfmt-yuv422m.rst | 274 + .../linux_tv/media/v4l/pixfmt-yuv422p.rst | 257 + .../linux_tv/media/v4l/pixfmt-yuv444m.rst | 294 + Documentation/linux_tv/media/v4l/pixfmt-yuyv.rst | 217 + Documentation/linux_tv/media/v4l/pixfmt-yvyu.rst | 216 + Documentation/linux_tv/media/v4l/pixfmt-z16.rst | 123 + Documentation/linux_tv/media/v4l/pixfmt.rst | 46 + Documentation/linux_tv/media/v4l/planar-apis.rst | 74 + Documentation/linux_tv/media/v4l/querycap.rst | 43 + .../linux_tv/media/v4l/remote_controllers.rst | 53 + .../media/v4l/remote_controllers_sysfs_nodes.rst | 152 + Documentation/linux_tv/media/v4l/rw.rst | 56 + Documentation/linux_tv/media/v4l/sdr-formats.rst | 30 + .../linux_tv/media/v4l/selection-api-002.rst | 37 + .../linux_tv/media/v4l/selection-api-003.rst | 29 + .../v4l/selection-api-003_files/selection.png | Bin 0 -> 11716 bytes .../linux_tv/media/v4l/selection-api-004.rst | 146 + .../linux_tv/media/v4l/selection-api-005.rst | 42 + .../linux_tv/media/v4l/selection-api-006.rst | 89 + Documentation/linux_tv/media/v4l/selection-api.rst | 27 + .../linux_tv/media/v4l/selections-common.rst | 34 + Documentation/linux_tv/media/v4l/standard.rst | 185 + Documentation/linux_tv/media/v4l/streaming-par.rst | 42 + .../linux_tv/media/v4l/subdev-formats.rst | 11701 +++++++++++++++++++ .../media/v4l/subdev-formats_files/bayer.png | Bin 0 -> 9725 bytes Documentation/linux_tv/media/v4l/tuner.rst | 91 + Documentation/linux_tv/media/v4l/user-func.rst | 92 + Documentation/linux_tv/media/v4l/userp.rst | 123 + .../linux_tv/media/v4l/v4l2-selection-flags.rst | 82 + .../linux_tv/media/v4l/v4l2-selection-targets.rst | 146 + Documentation/linux_tv/media/v4l/v4l2.rst | 392 + .../linux_tv/media/v4l/v4l2grab-example.rst | 28 + Documentation/linux_tv/media/v4l/v4l2grab.c.rst | 180 + Documentation/linux_tv/media/v4l/video.rst | 73 + Documentation/linux_tv/media/v4l/videodev.rst | 24 + .../linux_tv/media/v4l/vidioc-create-bufs.rst | 154 + .../linux_tv/media/v4l/vidioc-cropcap.rst | 175 + .../linux_tv/media/v4l/vidioc-dbg-g-chip-info.rst | 212 + .../linux_tv/media/v4l/vidioc-dbg-g-register.rst | 218 + .../linux_tv/media/v4l/vidioc-decoder-cmd.rst | 280 + .../linux_tv/media/v4l/vidioc-dqevent.rst | 581 + .../linux_tv/media/v4l/vidioc-dv-timings-cap.rst | 259 + .../linux_tv/media/v4l/vidioc-encoder-cmd.rst | 204 + .../linux_tv/media/v4l/vidioc-enum-dv-timings.rst | 128 + .../linux_tv/media/v4l/vidioc-enum-fmt.rst | 172 + .../media/v4l/vidioc-enum-frameintervals.rst | 282 + .../linux_tv/media/v4l/vidioc-enum-framesizes.rst | 299 + .../linux_tv/media/v4l/vidioc-enum-freq-bands.rst | 198 + .../linux_tv/media/v4l/vidioc-enumaudio.rst | 63 + .../linux_tv/media/v4l/vidioc-enumaudioout.rst | 66 + .../linux_tv/media/v4l/vidioc-enuminput.rst | 375 + .../linux_tv/media/v4l/vidioc-enumoutput.rst | 230 + .../linux_tv/media/v4l/vidioc-enumstd.rst | 450 + Documentation/linux_tv/media/v4l/vidioc-expbuf.rst | 205 + .../linux_tv/media/v4l/vidioc-g-audio.rst | 171 + .../linux_tv/media/v4l/vidioc-g-audioout.rst | 131 + Documentation/linux_tv/media/v4l/vidioc-g-crop.rst | 122 + Documentation/linux_tv/media/v4l/vidioc-g-ctrl.rst | 114 + .../linux_tv/media/v4l/vidioc-g-dv-timings.rst | 429 + Documentation/linux_tv/media/v4l/vidioc-g-edid.rst | 171 + .../linux_tv/media/v4l/vidioc-g-enc-index.rst | 218 + .../linux_tv/media/v4l/vidioc-g-ext-ctrls.rst | 498 + Documentation/linux_tv/media/v4l/vidioc-g-fbuf.rst | 509 + Documentation/linux_tv/media/v4l/vidioc-g-fmt.rst | 198 + .../linux_tv/media/v4l/vidioc-g-frequency.rst | 132 + .../linux_tv/media/v4l/vidioc-g-input.rst | 70 + .../linux_tv/media/v4l/vidioc-g-jpegcomp.rst | 191 + .../linux_tv/media/v4l/vidioc-g-modulator.rst | 264 + .../linux_tv/media/v4l/vidioc-g-output.rst | 72 + Documentation/linux_tv/media/v4l/vidioc-g-parm.rst | 358 + .../linux_tv/media/v4l/vidioc-g-priority.rst | 126 + .../linux_tv/media/v4l/vidioc-g-selection.rst | 218 + .../v4l/vidioc-g-selection_files/constraints.png | Bin 0 -> 3313 bytes .../linux_tv/media/v4l/vidioc-g-sliced-vbi-cap.rst | 284 + Documentation/linux_tv/media/v4l/vidioc-g-std.rst | 76 + .../linux_tv/media/v4l/vidioc-g-tuner.rst | 724 ++ .../linux_tv/media/v4l/vidioc-log-status.rst | 48 + .../linux_tv/media/v4l/vidioc-overlay.rst | 62 + .../linux_tv/media/v4l/vidioc-prepare-buf.rst | 69 + Documentation/linux_tv/media/v4l/vidioc-qbuf.rst | 158 + .../linux_tv/media/v4l/vidioc-query-dv-timings.rst | 91 + .../linux_tv/media/v4l/vidioc-querybuf.rst | 88 + .../linux_tv/media/v4l/vidioc-querycap.rst | 442 + .../linux_tv/media/v4l/vidioc-queryctrl.rst | 790 ++ .../linux_tv/media/v4l/vidioc-querystd.rst | 73 + .../linux_tv/media/v4l/vidioc-reqbufs.rst | 133 + .../linux_tv/media/v4l/vidioc-s-hw-freq-seek.rst | 187 + .../linux_tv/media/v4l/vidioc-streamon.rst | 111 + .../v4l/vidioc-subdev-enum-frame-interval.rst | 161 + .../media/v4l/vidioc-subdev-enum-frame-size.rst | 170 + .../media/v4l/vidioc-subdev-enum-mbus-code.rst | 123 + .../linux_tv/media/v4l/vidioc-subdev-g-crop.rst | 145 + .../linux_tv/media/v4l/vidioc-subdev-g-fmt.rst | 181 + .../media/v4l/vidioc-subdev-g-frame-interval.rst | 131 + .../media/v4l/vidioc-subdev-g-selection.rst | 153 + .../linux_tv/media/v4l/vidioc-subscribe-event.rst | 144 + Documentation/linux_tv/media/v4l/yuv-formats.rst | 66 + .../media_api_files/typical_media_device.pdf | Bin 0 -> 134268 bytes .../media_api_files/typical_media_device.svg | 28 + Documentation/linux_tv/net.h.rst | 70 + Documentation/linux_tv/video.h.rst | 291 + Documentation/linux_tv/videodev2.h.rst | 2311 ++++ 323 files changed, 74156 insertions(+) create mode 100644 Documentation/linux_tv/audio.h.rst create mode 100644 Documentation/linux_tv/ca.h.rst create mode 100644 Documentation/linux_tv/conf.py create mode 100644 Documentation/linux_tv/dmx.h.rst create mode 100644 Documentation/linux_tv/frontend.h.rst create mode 100644 Documentation/linux_tv/index.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_DISHNETWORK_SEND_LEGACY_CMD.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_GET_EVENT.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_GET_FRONTEND.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_READ_BER.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_READ_SIGNAL_STRENGTH.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_READ_SNR.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_READ_UNCORRECTED_BLOCKS.rst create mode 100644 Documentation/linux_tv/media/dvb/FE_SET_FRONTEND.rst create mode 100644 Documentation/linux_tv/media/dvb/audio.rst create mode 100644 Documentation/linux_tv/media/dvb/audio_data_types.rst create mode 100644 Documentation/linux_tv/media/dvb/audio_function_calls.rst create mode 100644 Documentation/linux_tv/media/dvb/audio_h.rst create mode 100644 Documentation/linux_tv/media/dvb/ca.rst create mode 100644 Documentation/linux_tv/media/dvb/ca_data_types.rst create mode 100644 Documentation/linux_tv/media/dvb/ca_function_calls.rst create mode 100644 Documentation/linux_tv/media/dvb/ca_h.rst create mode 100644 Documentation/linux_tv/media/dvb/demux.rst create mode 100644 Documentation/linux_tv/media/dvb/dmx_fcalls.rst create mode 100644 Documentation/linux_tv/media/dvb/dmx_h.rst create mode 100644 Documentation/linux_tv/media/dvb/dmx_types.rst create mode 100644 Documentation/linux_tv/media/dvb/dtv-fe-stats.rst create mode 100644 Documentation/linux_tv/media/dvb/dtv-properties.rst create mode 100644 Documentation/linux_tv/media/dvb/dtv-property.rst create mode 100644 Documentation/linux_tv/media/dvb/dtv-stats.rst create mode 100644 Documentation/linux_tv/media/dvb/dvb-fe-read-status.rst create mode 100644 Documentation/linux_tv/media/dvb/dvb-frontend-event.rst create mode 100644 Documentation/linux_tv/media/dvb/dvb-frontend-parameters.rst create mode 100644 Documentation/linux_tv/media/dvb/dvbapi.rst create mode 100644 Documentation/linux_tv/media/dvb/dvbproperty-006.rst create mode 100644 Documentation/linux_tv/media/dvb/dvbproperty.rst create mode 100644 Documentation/linux_tv/media/dvb/examples.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-bandwidth-t.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-diseqc-recv-slave-reply.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-diseqc-reset-overload.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-diseqc-send-burst.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-diseqc-send-master-cmd.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-enable-high-lnb-voltage.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-get-info.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-get-property.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-read-status.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-set-frontend-tune-mode.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-set-tone.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-set-voltage.rst create mode 100644 Documentation/linux_tv/media/dvb/fe-type-t.rst create mode 100644 Documentation/linux_tv/media/dvb/fe_property_parameters.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend-property-cable-systems.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend-property-satellite-systems.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend-property-terrestrial-systems.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend-stat-properties.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend_f_close.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend_f_open.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend_fcalls.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend_h.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend_legacy_api.rst create mode 100644 Documentation/linux_tv/media/dvb/frontend_legacy_dvbv3_api.rst create mode 100644 Documentation/linux_tv/media/dvb/intro.rst create mode 100644 Documentation/linux_tv/media/dvb/intro_files/dvbstb.pdf create mode 100644 Documentation/linux_tv/media/dvb/intro_files/dvbstb.png create mode 100644 Documentation/linux_tv/media/dvb/legacy_dvb_apis.rst create mode 100644 Documentation/linux_tv/media/dvb/net.rst create mode 100644 Documentation/linux_tv/media/dvb/net_h.rst create mode 100644 Documentation/linux_tv/media/dvb/query-dvb-frontend-info.rst create mode 100644 Documentation/linux_tv/media/dvb/video.rst create mode 100644 Documentation/linux_tv/media/dvb/video_function_calls.rst create mode 100644 Documentation/linux_tv/media/dvb/video_h.rst create mode 100644 Documentation/linux_tv/media/dvb/video_types.rst create mode 100644 Documentation/linux_tv/media/v4l/Remote_controllers_Intro.rst create mode 100644 Documentation/linux_tv/media/v4l/Remote_controllers_table_change.rst create mode 100644 Documentation/linux_tv/media/v4l/Remote_controllers_tables.rst create mode 100644 Documentation/linux_tv/media/v4l/app-pri.rst create mode 100644 Documentation/linux_tv/media/v4l/async.rst create mode 100644 Documentation/linux_tv/media/v4l/audio.rst create mode 100644 Documentation/linux_tv/media/v4l/biblio.rst create mode 100644 Documentation/linux_tv/media/v4l/buffer.rst create mode 100644 Documentation/linux_tv/media/v4l/capture-example.rst create mode 100644 Documentation/linux_tv/media/v4l/capture.c.rst create mode 100644 Documentation/linux_tv/media/v4l/colorspaces.rst create mode 100644 Documentation/linux_tv/media/v4l/common-defs.rst create mode 100644 Documentation/linux_tv/media/v4l/common.rst create mode 100644 Documentation/linux_tv/media/v4l/compat.rst create mode 100644 Documentation/linux_tv/media/v4l/control.rst create mode 100644 Documentation/linux_tv/media/v4l/controls.rst create mode 100644 Documentation/linux_tv/media/v4l/crop.rst create mode 100644 Documentation/linux_tv/media/v4l/crop_files/crop.gif create mode 100644 Documentation/linux_tv/media/v4l/crop_files/crop.pdf create mode 100644 Documentation/linux_tv/media/v4l/depth-formats.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-capture.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-codec.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-effect.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-event.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-osd.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-output.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-overlay.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-radio.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi_files/vbi_525.gif create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi_files/vbi_525.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi_files/vbi_625.gif create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi_files/vbi_625.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi_files/vbi_hsync.gif create mode 100644 Documentation/linux_tv/media/v4l/dev-raw-vbi_files/vbi_hsync.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-rds.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-sdr.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-sliced-vbi.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev.rst create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/pipeline.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/pipeline.png create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/subdev-image-processing-crop.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/subdev-image-processing-crop.svg create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/subdev-image-processing-full.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/subdev-image-processing-full.svg create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/subdev-image-processing-scaling-multi-source.pdf create mode 100644 Documentation/linux_tv/media/v4l/dev-subdev_files/subdev-image-processing-scaling-multi-source.svg create mode 100644 Documentation/linux_tv/media/v4l/dev-teletext.rst create mode 100644 Documentation/linux_tv/media/v4l/devices.rst create mode 100644 Documentation/linux_tv/media/v4l/diff-v4l.rst create mode 100644 Documentation/linux_tv/media/v4l/dmabuf.rst create mode 100644 Documentation/linux_tv/media/v4l/driver.rst create mode 100644 Documentation/linux_tv/media/v4l/dv-timings.rst create mode 100644 Documentation/linux_tv/media/v4l/extended-controls.rst create mode 100644 Documentation/linux_tv/media/v4l/fdl-appendix.rst create mode 100644 Documentation/linux_tv/media/v4l/field-order.rst create mode 100644 Documentation/linux_tv/media/v4l/field-order_files/fieldseq_bt.gif create mode 100644 Documentation/linux_tv/media/v4l/field-order_files/fieldseq_bt.pdf create mode 100644 Documentation/linux_tv/media/v4l/field-order_files/fieldseq_tb.gif create mode 100644 Documentation/linux_tv/media/v4l/field-order_files/fieldseq_tb.pdf create mode 100644 Documentation/linux_tv/media/v4l/format.rst create mode 100644 Documentation/linux_tv/media/v4l/func-close.rst create mode 100644 Documentation/linux_tv/media/v4l/func-ioctl.rst create mode 100644 Documentation/linux_tv/media/v4l/func-mmap.rst create mode 100644 Documentation/linux_tv/media/v4l/func-munmap.rst create mode 100644 Documentation/linux_tv/media/v4l/func-open.rst create mode 100644 Documentation/linux_tv/media/v4l/func-poll.rst create mode 100644 Documentation/linux_tv/media/v4l/func-read.rst create mode 100644 Documentation/linux_tv/media/v4l/func-select.rst create mode 100644 Documentation/linux_tv/media/v4l/func-write.rst create mode 100644 Documentation/linux_tv/media/v4l/gen-errors.rst create mode 100644 Documentation/linux_tv/media/v4l/hist-v4l2.rst create mode 100644 Documentation/linux_tv/media/v4l/io.rst create mode 100644 Documentation/linux_tv/media/v4l/keytable.c.rst create mode 100644 Documentation/linux_tv/media/v4l/libv4l-introduction.rst create mode 100644 Documentation/linux_tv/media/v4l/libv4l.rst create mode 100644 Documentation/linux_tv/media/v4l/lirc_dev_intro.rst create mode 100644 Documentation/linux_tv/media/v4l/lirc_device_interface.rst create mode 100644 Documentation/linux_tv/media/v4l/lirc_ioctl.rst create mode 100644 Documentation/linux_tv/media/v4l/lirc_read.rst create mode 100644 Documentation/linux_tv/media/v4l/lirc_write.rst create mode 100644 Documentation/linux_tv/media/v4l/media-controller-intro.rst create mode 100644 Documentation/linux_tv/media/v4l/media-controller-model.rst create mode 100644 Documentation/linux_tv/media/v4l/media-controller.rst create mode 100644 Documentation/linux_tv/media/v4l/media-func-close.rst create mode 100644 Documentation/linux_tv/media/v4l/media-func-ioctl.rst create mode 100644 Documentation/linux_tv/media/v4l/media-func-open.rst create mode 100644 Documentation/linux_tv/media/v4l/media-ioc-device-info.rst create mode 100644 Documentation/linux_tv/media/v4l/media-ioc-enum-entities.rst create mode 100644 Documentation/linux_tv/media/v4l/media-ioc-enum-links.rst create mode 100644 Documentation/linux_tv/media/v4l/media-ioc-g-topology.rst create mode 100644 Documentation/linux_tv/media/v4l/media-ioc-setup-link.rst create mode 100644 Documentation/linux_tv/media/v4l/media-types.rst create mode 100644 Documentation/linux_tv/media/v4l/mmap.rst create mode 100644 Documentation/linux_tv/media/v4l/open.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-002.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-003.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-004.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-006.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-007.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-008.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-013.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-grey.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-indexed.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-m420.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv12.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv12m.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv12mt.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv12mt_files/nv12mt.gif create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv12mt_files/nv12mt_example.gif create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv16.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv16m.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-nv24.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-packed-rgb.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-packed-yuv.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-reserved.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-rgb.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sbggr16.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sbggr8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sdr-cs08.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sdr-cs14le.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sdr-cu08.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sdr-cu16le.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sdr-ru12le.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sgbrg8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-sgrbg8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-srggb10.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-srggb10alaw8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-srggb10dpcm8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-srggb10p.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-srggb12.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-srggb8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-uv8.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-uyvy.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-vyuy.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y10.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y10b.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y12.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y12i.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y16-be.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y16.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y41p.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-y8i.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv410.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv411p.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv420.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv420m.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv422m.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv422p.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuv444m.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yuyv.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-yvyu.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt-z16.rst create mode 100644 Documentation/linux_tv/media/v4l/pixfmt.rst create mode 100644 Documentation/linux_tv/media/v4l/planar-apis.rst create mode 100644 Documentation/linux_tv/media/v4l/querycap.rst create mode 100644 Documentation/linux_tv/media/v4l/remote_controllers.rst create mode 100644 Documentation/linux_tv/media/v4l/remote_controllers_sysfs_nodes.rst create mode 100644 Documentation/linux_tv/media/v4l/rw.rst create mode 100644 Documentation/linux_tv/media/v4l/sdr-formats.rst create mode 100644 Documentation/linux_tv/media/v4l/selection-api-002.rst create mode 100644 Documentation/linux_tv/media/v4l/selection-api-003.rst create mode 100644 Documentation/linux_tv/media/v4l/selection-api-003_files/selection.png create mode 100644 Documentation/linux_tv/media/v4l/selection-api-004.rst create mode 100644 Documentation/linux_tv/media/v4l/selection-api-005.rst create mode 100644 Documentation/linux_tv/media/v4l/selection-api-006.rst create mode 100644 Documentation/linux_tv/media/v4l/selection-api.rst create mode 100644 Documentation/linux_tv/media/v4l/selections-common.rst create mode 100644 Documentation/linux_tv/media/v4l/standard.rst create mode 100644 Documentation/linux_tv/media/v4l/streaming-par.rst create mode 100644 Documentation/linux_tv/media/v4l/subdev-formats.rst create mode 100644 Documentation/linux_tv/media/v4l/subdev-formats_files/bayer.png create mode 100644 Documentation/linux_tv/media/v4l/tuner.rst create mode 100644 Documentation/linux_tv/media/v4l/user-func.rst create mode 100644 Documentation/linux_tv/media/v4l/userp.rst create mode 100644 Documentation/linux_tv/media/v4l/v4l2-selection-flags.rst create mode 100644 Documentation/linux_tv/media/v4l/v4l2-selection-targets.rst create mode 100644 Documentation/linux_tv/media/v4l/v4l2.rst create mode 100644 Documentation/linux_tv/media/v4l/v4l2grab-example.rst create mode 100644 Documentation/linux_tv/media/v4l/v4l2grab.c.rst create mode 100644 Documentation/linux_tv/media/v4l/video.rst create mode 100644 Documentation/linux_tv/media/v4l/videodev.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-create-bufs.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-cropcap.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-dbg-g-chip-info.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-dbg-g-register.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-decoder-cmd.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-dqevent.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-dv-timings-cap.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-encoder-cmd.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enum-dv-timings.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enum-fmt.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enum-frameintervals.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enum-framesizes.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enum-freq-bands.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enumaudio.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enumaudioout.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enuminput.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enumoutput.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-enumstd.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-expbuf.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-audio.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-audioout.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-crop.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-ctrl.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-dv-timings.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-edid.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-enc-index.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-ext-ctrls.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-fbuf.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-fmt.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-frequency.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-input.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-jpegcomp.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-modulator.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-output.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-parm.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-priority.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-selection.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-selection_files/constraints.png create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-sliced-vbi-cap.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-std.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-g-tuner.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-log-status.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-overlay.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-prepare-buf.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-qbuf.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-query-dv-timings.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-querybuf.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-querycap.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-queryctrl.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-querystd.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-reqbufs.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-s-hw-freq-seek.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-streamon.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-enum-frame-interval.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-enum-frame-size.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-enum-mbus-code.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-g-crop.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-g-fmt.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-g-frame-interval.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subdev-g-selection.rst create mode 100644 Documentation/linux_tv/media/v4l/vidioc-subscribe-event.rst create mode 100644 Documentation/linux_tv/media/v4l/yuv-formats.rst create mode 100644 Documentation/linux_tv/media_api_files/typical_media_device.pdf create mode 100644 Documentation/linux_tv/media_api_files/typical_media_device.svg create mode 100644 Documentation/linux_tv/net.h.rst create mode 100644 Documentation/linux_tv/video.h.rst create mode 100644 Documentation/linux_tv/videodev2.h.rst (limited to 'Documentation') diff --git a/Documentation/index.rst b/Documentation/index.rst index f92854f01773..8bc7bf4e6041 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -14,6 +14,7 @@ Contents: :maxdepth: 2 kernel-documentation + linux_tv/index Indices and tables ================== diff --git a/Documentation/linux_tv/audio.h.rst b/Documentation/linux_tv/audio.h.rst new file mode 100644 index 000000000000..abf29027f8ea --- /dev/null +++ b/Documentation/linux_tv/audio.h.rst @@ -0,0 +1,153 @@ +.. -*- coding: utf-8; mode: rst -*- + +file: audio.h +============= + +.. code-block:: c + + /* + * audio.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + #ifndef _DVBAUDIO_H_ + #define _DVBAUDIO_H_ + + #include + + typedef enum { + AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ + AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */ + } audio_stream_source_t; + + + typedef enum { + AUDIO_STOPPED, /* Device is stopped */ + AUDIO_PLAYING, /* Device is currently playing */ + AUDIO_PAUSED /* Device is paused */ + } audio_play_state_t; + + + typedef enum { + AUDIO_STEREO, + AUDIO_MONO_LEFT, + AUDIO_MONO_RIGHT, + AUDIO_MONO, + AUDIO_STEREO_SWAPPED + } audio_channel_select_t; + + + typedef struct audio_mixer { + unsigned int volume_left; + unsigned int volume_right; + // what else do we need? bass, pass-through, ... + } audio_mixer_t; + + + typedef struct audio_status { + int AV_sync_state; /* sync audio and video? */ + int mute_state; /* audio is muted */ + audio_play_state_t play_state; /* current playback state */ + audio_stream_source_t stream_source; /* current stream source */ + audio_channel_select_t channel_select; /* currently selected channel */ + int bypass_mode; /* pass on audio data to */ + audio_mixer_t mixer_state; /* current mixer state */ + } audio_status_t; /* separate decoder hardware */ + + + typedef + struct audio_karaoke { /* if Vocal1 or Vocal2 are non-zero, they get mixed */ + int vocal1; /* into left and right t at 70% each */ + int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets*/ + int melody; /* mixed into the left channel and */ + /* Vocal2 into the right channel at 100% each. */ + /* if Melody is non-zero, the melody channel gets mixed*/ + } audio_karaoke_t; /* into left and right */ + + + typedef __u16 audio_attributes_t; + /* bits: descr. */ + /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ + /* 12 multichannel extension */ + /* 11-10 audio type (0=not spec, 1=language included) */ + /* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ + /* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */ + /* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ + /* 2- 0 number of audio channels (n+1 channels) */ + + + /* for GET_CAPABILITIES and SET_FORMAT, the latter should only set one bit */ + #define AUDIO_CAP_DTS 1 + #define AUDIO_CAP_LPCM 2 + #define AUDIO_CAP_MP1 4 + #define AUDIO_CAP_MP2 8 + #define AUDIO_CAP_MP3 16 + #define AUDIO_CAP_AAC 32 + #define AUDIO_CAP_OGG 64 + #define AUDIO_CAP_SDDS 128 + #define AUDIO_CAP_AC3 256 + + #define AUDIO_STOP _IO('o', 1) + #define AUDIO_PLAY _IO('o', 2) + #define AUDIO_PAUSE _IO('o', 3) + #define AUDIO_CONTINUE _IO('o', 4) + #define AUDIO_SELECT_SOURCE _IO('o', 5) + #define AUDIO_SET_MUTE _IO('o', 6) + #define AUDIO_SET_AV_SYNC _IO('o', 7) + #define AUDIO_SET_BYPASS_MODE _IO('o', 8) + #define AUDIO_CHANNEL_SELECT _IO('o', 9) + #define AUDIO_GET_STATUS _IOR('o', 10, audio_status_t) + + #define AUDIO_GET_CAPABILITIES _IOR('o', 11, unsigned int) + #define AUDIO_CLEAR_BUFFER _IO('o', 12) + #define AUDIO_SET_ID _IO('o', 13) + #define AUDIO_SET_MIXER _IOW('o', 14, audio_mixer_t) + #define AUDIO_SET_STREAMTYPE _IO('o', 15) + #define AUDIO_SET_EXT_ID _IO('o', 16) + #define AUDIO_SET_ATTRIBUTES _IOW('o', 17, audio_attributes_t) + #define AUDIO_SET_KARAOKE _IOW('o', 18, audio_karaoke_t) + + /** + * AUDIO_GET_PTS + * + * Read the 33 bit presentation time stamp as defined + * in ITU T-REC-H.222.0 / ISO/IEC 13818-1. + * + * The PTS should belong to the currently played + * frame if possible, but may also be a value close to it + * like the PTS of the last decoded frame or the last PTS + * extracted by the PES parser. + */ + #define AUDIO_GET_PTS _IOR('o', 19, __u64) + #define AUDIO_BILINGUAL_CHANNEL_SELECT _IO('o', 20) + + #endif /* _DVBAUDIO_H_ */ + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/ca.h.rst b/Documentation/linux_tv/ca.h.rst new file mode 100644 index 000000000000..b69ce287aa8c --- /dev/null +++ b/Documentation/linux_tv/ca.h.rst @@ -0,0 +1,108 @@ +.. -*- coding: utf-8; mode: rst -*- + +file: ca.h +========== + +.. code-block:: c + + /* + * ca.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + #ifndef _DVBCA_H_ + #define _DVBCA_H_ + + /* slot interface types and info */ + + typedef struct ca_slot_info { + int num; /* slot number */ + + int type; /* CA interface this slot supports */ + #define CA_CI 1 /* CI high level interface */ + #define CA_CI_LINK 2 /* CI link layer level interface */ + #define CA_CI_PHYS 4 /* CI physical layer level interface */ + #define CA_DESCR 8 /* built-in descrambler */ + #define CA_SC 128 /* simple smart card interface */ + + unsigned int flags; + #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ + #define CA_CI_MODULE_READY 2 + } ca_slot_info_t; + + + /* descrambler types and info */ + + typedef struct ca_descr_info { + unsigned int num; /* number of available descramblers (keys) */ + unsigned int type; /* type of supported scrambling system */ + #define CA_ECD 1 + #define CA_NDS 2 + #define CA_DSS 4 + } ca_descr_info_t; + + typedef struct ca_caps { + unsigned int slot_num; /* total number of CA card and module slots */ + unsigned int slot_type; /* OR of all supported types */ + unsigned int descr_num; /* total number of descrambler slots (keys) */ + unsigned int descr_type; /* OR of all supported types */ + } ca_caps_t; + + /* a message to/from a CI-CAM */ + typedef struct ca_msg { + unsigned int index; + unsigned int type; + unsigned int length; + unsigned char msg[256]; + } ca_msg_t; + + typedef struct ca_descr { + unsigned int index; + unsigned int parity; /* 0 == even, 1 == odd */ + unsigned char cw[8]; + } ca_descr_t; + + typedef struct ca_pid { + unsigned int pid; + int index; /* -1 == disable*/ + } ca_pid_t; + + #define CA_RESET _IO('o', 128) + #define CA_GET_CAP _IOR('o', 129, ca_caps_t) + #define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t) + #define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) + #define CA_GET_MSG _IOR('o', 132, ca_msg_t) + #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) + #define CA_SET_DESCR _IOW('o', 134, ca_descr_t) + #define CA_SET_PID _IOW('o', 135, ca_pid_t) + + #endif + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/conf.py b/Documentation/linux_tv/conf.py new file mode 100644 index 000000000000..8013c921256b --- /dev/null +++ b/Documentation/linux_tv/conf.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8; mode: python -*- +# +# This is the project specific sphinx-build configuration, which is loaded from +# the base configuration file (``../conf.py``). About config values consult: +# +# * http://www.sphinx-doc.org/en/stable/config.html +# +# While setting values here, please take care to not overwrite common needed +# configurations. This means, do not *overwrite* composite values (e.g. the +# list- or dictionary-value of "latex_elements" resp. "extensions") by +# thoughtless assignments. Manipulate composite values always by *update* +# (dict-values) or extend (list-values). Nevertheless, if you know what you are +# doing, you are free to *overwrite* values to your needs. +# +# useful preset names: +# +# * BASE_FOLDER: the folder where the top conf.py is located +# * main_name: the basename of this project-folder + +# Set parser's default kernel-doc mode ``reST|kernel-doc``. +kernel_doc_mode = "kernel-doc" + +# ------------------------------------------------------------------------------ +# General configuration +# ------------------------------------------------------------------------------ + +project = u'LINUX MEDIA INFRASTRUCTURE API' +copyright = u'2009-2015 : LinuxTV Developers' +author = u'The LinuxTV Developers' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +#version = 'v4.7' +# The full version, including alpha/beta/rc tags. +#release = 'v4.7-rc2' + +# extlinks["man"] = ('http://manpages.ubuntu.com/cgi-bin/search.py?q=%s', ' ') + +# intersphinx_mapping['kernel-doc'] = ('http://return42.github.io/sphkerneldoc/books/kernel-doc-HOWTO/', None) + +extensions.extend([ + # 'sphinx.ext.pngmath' + #, 'sphinx.ext.mathjax' +]) + +# ------------------------------------------------------------------------------ +# Options for HTML output +# ------------------------------------------------------------------------------ + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = pathjoin(BASE_FOLDER, "_tex", "logo.png") + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path.extend([]) + +# Output file base name for HTML help builder. +htmlhelp_basename = main_name + +# ------------------------------------------------------------------------------ +# Options for rst2pdf output +# ------------------------------------------------------------------------------ + +# Grouping the document tree into PDF files. List of tuples +# (source start file, target name, title, author, options). +# +# The options element is a dictionary that lets you override +# this config per-document. +# For example, +# ('index', u'MyProject', u'My Project', u'Author Name', +# dict(pdf_compressed = True)) +# would mean that specific document would be compressed +# regardless of the global pdf_compressed setting. +# +# further: http://rst2pdf.ralsina.me/handbook.html#sphinx + +# FIXME: at this time, the rst2pdf fails with a bug +#pdf_documents = [ +# (master_doc, main_name, project, author) +# , ] + +# If false, no index is generated. +pdf_use_index = False + +# How many levels deep should the table of contents be? +pdf_toc_depth = 3 + +# Add section number to section references +pdf_use_numbered_links = False + +# Background images fitting mode +pdf_fit_background_mode = 'scale' + + +# ------------------------------------------------------------------------------ +# Options for manual page output +# ------------------------------------------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +# man_pages = [ +# (master_doc, 'kernel-doc', u'Kernel-Doc', +# [author], 1) +# ] + +# If true, show URL addresses after external links. +#man_show_urls = False + +# ------------------------------------------------------------------------------ +# Options for Texinfo output +# ------------------------------------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +# texinfo_documents = [ +# (master_doc, 'Kernel-Doc', u'Kernel-Doc Documentation', +# author, 'Kernel-Doc', 'One line description of project.', +# 'Miscellaneous'), +# ] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + +# ------------------------------------------------------------------------------ +# Options for Epub output +# ------------------------------------------------------------------------------ + +# Bibliographic Dublin Core info. +# epub_title = project +# epub_author = author +# epub_publisher = author +# epub_copyright = copyright + +# The basename for the epub file. It defaults to the project name. +#epub_basename = project + +# The HTML theme for the epub output. Since the default themes are not +# optimized for small screen space, using the same theme for HTML and epub +# output is usually not wise. This defaults to 'epub', a theme designed to save +# visual space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or 'en' if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files.extend([]) + +# HTML files that should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files.extend([]) + +# A list of files that should not be packed into the epub file. +epub_exclude_files.extend([]) + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the Pillow. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True + diff --git a/Documentation/linux_tv/dmx.h.rst b/Documentation/linux_tv/dmx.h.rst new file mode 100644 index 000000000000..9ced07899e57 --- /dev/null +++ b/Documentation/linux_tv/dmx.h.rst @@ -0,0 +1,173 @@ +.. -*- coding: utf-8; mode: rst -*- + +file: dmx.h +=========== + +.. code-block:: c + + /* + * dmx.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + #ifndef _UAPI_DVBDMX_H_ + #define _UAPI_DVBDMX_H_ + + #include + #ifndef __KERNEL__ + #include + #endif + + + #define DMX_FILTER_SIZE 16 + + enum dmx_output + { + DMX_OUT_DECODER, /* Streaming directly to decoder. */ + DMX_OUT_TAP, /* Output going to a memory buffer */ + /* (to be retrieved via the read command).*/ + DMX_OUT_TS_TAP, /* Output multiplexed into a new TS */ + /* (to be retrieved by reading from the */ + /* logical DVR device). */ + DMX_OUT_TSDEMUX_TAP /* Like TS_TAP but retrieved from the DMX device */ + }; + + typedef enum dmx_output dmx_output_t; + + typedef enum dmx_input + { + DMX_IN_FRONTEND, /* Input from a front-end device. */ + DMX_IN_DVR /* Input from the logical DVR device. */ + } dmx_input_t; + + + typedef enum dmx_ts_pes + { + DMX_PES_AUDIO0, + DMX_PES_VIDEO0, + DMX_PES_TELETEXT0, + DMX_PES_SUBTITLE0, + DMX_PES_PCR0, + + DMX_PES_AUDIO1, + DMX_PES_VIDEO1, + DMX_PES_TELETEXT1, + DMX_PES_SUBTITLE1, + DMX_PES_PCR1, + + DMX_PES_AUDIO2, + DMX_PES_VIDEO2, + DMX_PES_TELETEXT2, + DMX_PES_SUBTITLE2, + DMX_PES_PCR2, + + DMX_PES_AUDIO3, + DMX_PES_VIDEO3, + DMX_PES_TELETEXT3, + DMX_PES_SUBTITLE3, + DMX_PES_PCR3, + + DMX_PES_OTHER + } dmx_pes_type_t; + + #define DMX_PES_AUDIO DMX_PES_AUDIO0 + #define DMX_PES_VIDEO DMX_PES_VIDEO0 + #define DMX_PES_TELETEXT DMX_PES_TELETEXT0 + #define DMX_PES_SUBTITLE DMX_PES_SUBTITLE0 + #define DMX_PES_PCR DMX_PES_PCR0 + + + typedef struct dmx_filter + { + __u8 filter[DMX_FILTER_SIZE]; + __u8 mask[DMX_FILTER_SIZE]; + __u8 mode[DMX_FILTER_SIZE]; + } dmx_filter_t; + + + struct dmx_sct_filter_params + { + __u16 pid; + dmx_filter_t filter; + __u32 timeout; + __u32 flags; + #define DMX_CHECK_CRC 1 + #define DMX_ONESHOT 2 + #define DMX_IMMEDIATE_START 4 + #define DMX_KERNEL_CLIENT 0x8000 + }; + + + struct dmx_pes_filter_params + { + __u16 pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pes_type; + __u32 flags; + }; + + typedef struct dmx_caps { + __u32 caps; + int num_decoders; + } dmx_caps_t; + + typedef enum dmx_source { + DMX_SOURCE_FRONT0 = 0, + DMX_SOURCE_FRONT1, + DMX_SOURCE_FRONT2, + DMX_SOURCE_FRONT3, + DMX_SOURCE_DVR0 = 16, + DMX_SOURCE_DVR1, + DMX_SOURCE_DVR2, + DMX_SOURCE_DVR3 + } dmx_source_t; + + struct dmx_stc { + unsigned int num; /* input : which STC? 0..N */ + unsigned int base; /* output: divisor for stc to get 90 kHz clock */ + __u64 stc; /* output: stc in 'base'*90 kHz units */ + }; + + #define DMX_START _IO('o', 41) + #define DMX_STOP _IO('o', 42) + #define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params) + #define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params) + #define DMX_SET_BUFFER_SIZE _IO('o', 45) + #define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5]) + #define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t) + #define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t) + #define DMX_GET_STC _IOWR('o', 50, struct dmx_stc) + #define DMX_ADD_PID _IOW('o', 51, __u16) + #define DMX_REMOVE_PID _IOW('o', 52, __u16) + + #endif /* _UAPI_DVBDMX_H_ */ + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/frontend.h.rst b/Documentation/linux_tv/frontend.h.rst new file mode 100644 index 000000000000..1b65b2037778 --- /dev/null +++ b/Documentation/linux_tv/frontend.h.rst @@ -0,0 +1,620 @@ +.. -*- coding: utf-8; mode: rst -*- + +file: frontend.h +================ + +.. code-block:: c + + /* + * frontend.h + * + * Copyright (C) 2000 Marcus Metzler + * Ralph Metzler + * Holger Waechtler + * Andre Draszik + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + #ifndef _DVBFRONTEND_H_ + #define _DVBFRONTEND_H_ + + #include + + enum fe_type { + FE_QPSK, + FE_QAM, + FE_OFDM, + FE_ATSC + }; + + enum fe_caps { + FE_IS_STUPID = 0, + FE_CAN_INVERSION_AUTO = 0x1, + FE_CAN_FEC_1_2 = 0x2, + FE_CAN_FEC_2_3 = 0x4, + FE_CAN_FEC_3_4 = 0x8, + FE_CAN_FEC_4_5 = 0x10, + FE_CAN_FEC_5_6 = 0x20, + FE_CAN_FEC_6_7 = 0x40, + FE_CAN_FEC_7_8 = 0x80, + FE_CAN_FEC_8_9 = 0x100, + FE_CAN_FEC_AUTO = 0x200, + FE_CAN_QPSK = 0x400, + FE_CAN_QAM_16 = 0x800, + FE_CAN_QAM_32 = 0x1000, + FE_CAN_QAM_64 = 0x2000, + FE_CAN_QAM_128 = 0x4000, + FE_CAN_QAM_256 = 0x8000, + FE_CAN_QAM_AUTO = 0x10000, + FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000, + FE_CAN_BANDWIDTH_AUTO = 0x40000, + FE_CAN_GUARD_INTERVAL_AUTO = 0x80000, + FE_CAN_HIERARCHY_AUTO = 0x100000, + FE_CAN_8VSB = 0x200000, + FE_CAN_16VSB = 0x400000, + FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */ + FE_CAN_MULTISTREAM = 0x4000000, /* frontend supports multistream filtering */ + FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */ + FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */ + FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */ + FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */ + FE_CAN_MUTE_TS = 0x80000000 /* frontend can stop spurious TS data output */ + }; + + struct dvb_frontend_info { + char name[128]; + enum fe_type type; /* DEPRECATED. Use DTV_ENUM_DELSYS instead */ + __u32 frequency_min; + __u32 frequency_max; + __u32 frequency_stepsize; + __u32 frequency_tolerance; + __u32 symbol_rate_min; + __u32 symbol_rate_max; + __u32 symbol_rate_tolerance; /* ppm */ + __u32 notifier_delay; /* DEPRECATED */ + enum fe_caps caps; + }; + + + /** + * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for + * the meaning of this struct... + */ + struct dvb_diseqc_master_cmd { + __u8 msg [6]; /* { framing, address, command, data [3] } */ + __u8 msg_len; /* valid values are 3...6 */ + }; + + struct dvb_diseqc_slave_reply { + __u8 msg [4]; /* { framing, data [3] } */ + __u8 msg_len; /* valid values are 0...4, 0 means no msg */ + int timeout; /* return from ioctl after timeout ms with */ + }; /* errorcode when no message was received */ + + enum fe_sec_voltage { + SEC_VOLTAGE_13, + SEC_VOLTAGE_18, + SEC_VOLTAGE_OFF + }; + + enum fe_sec_tone_mode { + SEC_TONE_ON, + SEC_TONE_OFF + }; + + enum fe_sec_mini_cmd { + SEC_MINI_A, + SEC_MINI_B + }; + + /** + * enum fe_status - enumerates the possible frontend status + * @FE_HAS_SIGNAL: found something above the noise level + * @FE_HAS_CARRIER: found a DVB signal + * @FE_HAS_VITERBI: FEC is stable + * @FE_HAS_SYNC: found sync bytes + * @FE_HAS_LOCK: everything's working + * @FE_TIMEDOUT: no lock within the last ~2 seconds + * @FE_REINIT: frontend was reinitialized, application is recommended + * to reset DiSEqC, tone and parameters + */ + enum fe_status { + FE_HAS_SIGNAL = 0x01, + FE_HAS_CARRIER = 0x02, + FE_HAS_VITERBI = 0x04, + FE_HAS_SYNC = 0x08, + FE_HAS_LOCK = 0x10, + FE_TIMEDOUT = 0x20, + FE_REINIT = 0x40, + }; + + enum fe_spectral_inversion { + INVERSION_OFF, + INVERSION_ON, + INVERSION_AUTO + }; + + enum fe_code_rate { + FEC_NONE = 0, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_4_5, + FEC_5_6, + FEC_6_7, + FEC_7_8, + FEC_8_9, + FEC_AUTO, + FEC_3_5, + FEC_9_10, + FEC_2_5, + }; + + enum fe_modulation { + QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256, + QAM_AUTO, + VSB_8, + VSB_16, + PSK_8, + APSK_16, + APSK_32, + DQPSK, + QAM_4_NR, + }; + + enum fe_transmit_mode { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K, + TRANSMISSION_MODE_AUTO, + TRANSMISSION_MODE_4K, + TRANSMISSION_MODE_1K, + TRANSMISSION_MODE_16K, + TRANSMISSION_MODE_32K, + TRANSMISSION_MODE_C1, + TRANSMISSION_MODE_C3780, + }; + + enum fe_guard_interval { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4, + GUARD_INTERVAL_AUTO, + GUARD_INTERVAL_1_128, + GUARD_INTERVAL_19_128, + GUARD_INTERVAL_19_256, + GUARD_INTERVAL_PN420, + GUARD_INTERVAL_PN595, + GUARD_INTERVAL_PN945, + }; + + enum fe_hierarchy { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4, + HIERARCHY_AUTO + }; + + enum fe_interleaving { + INTERLEAVING_NONE, + INTERLEAVING_AUTO, + INTERLEAVING_240, + INTERLEAVING_720, + }; + + /* S2API Commands */ + #define DTV_UNDEFINED 0 + #define DTV_TUNE 1 + #define DTV_CLEAR 2 + #define DTV_FREQUENCY 3 + #define DTV_MODULATION 4 + #define DTV_BANDWIDTH_HZ 5 + #define DTV_INVERSION 6 + #define DTV_DISEQC_MASTER 7 + #define DTV_SYMBOL_RATE 8 + #define DTV_INNER_FEC 9 + #define DTV_VOLTAGE 10 + #define DTV_TONE 11 + #define DTV_PILOT 12 + #define DTV_ROLLOFF 13 + #define DTV_DISEQC_SLAVE_REPLY 14 + + /* Basic enumeration set for querying unlimited capabilities */ + #define DTV_FE_CAPABILITY_COUNT 15 + #define DTV_FE_CAPABILITY 16 + #define DTV_DELIVERY_SYSTEM 17 + + /* ISDB-T and ISDB-Tsb */ + #define DTV_ISDBT_PARTIAL_RECEPTION 18 + #define DTV_ISDBT_SOUND_BROADCASTING 19 + + #define DTV_ISDBT_SB_SUBCHANNEL_ID 20 + #define DTV_ISDBT_SB_SEGMENT_IDX 21 + #define DTV_ISDBT_SB_SEGMENT_COUNT 22 + + #define DTV_ISDBT_LAYERA_FEC 23 + #define DTV_ISDBT_LAYERA_MODULATION 24 + #define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25 + #define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26 + + #define DTV_ISDBT_LAYERB_FEC 27 + #define DTV_ISDBT_LAYERB_MODULATION 28 + #define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29 + #define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30 + + #define DTV_ISDBT_LAYERC_FEC 31 + #define DTV_ISDBT_LAYERC_MODULATION 32 + #define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33 + #define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34 + + #define DTV_API_VERSION 35 + + #define DTV_CODE_RATE_HP 36 + #define DTV_CODE_RATE_LP 37 + #define DTV_GUARD_INTERVAL 38 + #define DTV_TRANSMISSION_MODE 39 + #define DTV_HIERARCHY 40 + + #define DTV_ISDBT_LAYER_ENABLED 41 + + #define DTV_STREAM_ID 42 + #define DTV_ISDBS_TS_ID_LEGACY DTV_STREAM_ID + #define DTV_DVBT2_PLP_ID_LEGACY 43 + + #define DTV_ENUM_DELSYS 44 + + /* ATSC-MH */ + #define DTV_ATSCMH_FIC_VER 45 + #define DTV_ATSCMH_PARADE_ID 46 + #define DTV_ATSCMH_NOG 47 + #define DTV_ATSCMH_TNOG 48 + #define DTV_ATSCMH_SGN 49 + #define DTV_ATSCMH_PRC 50 + #define DTV_ATSCMH_RS_FRAME_MODE 51 + #define DTV_ATSCMH_RS_FRAME_ENSEMBLE 52 + #define DTV_ATSCMH_RS_CODE_MODE_PRI 53 + #define DTV_ATSCMH_RS_CODE_MODE_SEC 54 + #define DTV_ATSCMH_SCCC_BLOCK_MODE 55 + #define DTV_ATSCMH_SCCC_CODE_MODE_A 56 + #define DTV_ATSCMH_SCCC_CODE_MODE_B 57 + #define DTV_ATSCMH_SCCC_CODE_MODE_C 58 + #define DTV_ATSCMH_SCCC_CODE_MODE_D 59 + + #define DTV_INTERLEAVING 60 + #define DTV_LNA 61 + + /* Quality parameters */ + #define DTV_STAT_SIGNAL_STRENGTH 62 + #define DTV_STAT_CNR 63 + #define DTV_STAT_PRE_ERROR_BIT_COUNT 64 + #define DTV_STAT_PRE_TOTAL_BIT_COUNT 65 + #define DTV_STAT_POST_ERROR_BIT_COUNT 66 + #define DTV_STAT_POST_TOTAL_BIT_COUNT 67 + #define DTV_STAT_ERROR_BLOCK_COUNT 68 + #define DTV_STAT_TOTAL_BLOCK_COUNT 69 + + #define DTV_MAX_COMMAND DTV_STAT_TOTAL_BLOCK_COUNT + + enum fe_pilot { + PILOT_ON, + PILOT_OFF, + PILOT_AUTO, + }; + + enum fe_rolloff { + ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */ + ROLLOFF_20, + ROLLOFF_25, + ROLLOFF_AUTO, + }; + + enum fe_delivery_system { + SYS_UNDEFINED, + SYS_DVBC_ANNEX_A, + SYS_DVBC_ANNEX_B, + SYS_DVBT, + SYS_DSS, + SYS_DVBS, + SYS_DVBS2, + SYS_DVBH, + SYS_ISDBT, + SYS_ISDBS, + SYS_ISDBC, + SYS_ATSC, + SYS_ATSCMH, + SYS_DTMB, + SYS_CMMB, + SYS_DAB, + SYS_DVBT2, + SYS_TURBO, + SYS_DVBC_ANNEX_C, + }; + + /* backward compatibility */ + #define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A + #define SYS_DMBTH SYS_DTMB /* DMB-TH is legacy name, use DTMB instead */ + + /* ATSC-MH */ + + enum atscmh_sccc_block_mode { + ATSCMH_SCCC_BLK_SEP = 0, + ATSCMH_SCCC_BLK_COMB = 1, + ATSCMH_SCCC_BLK_RES = 2, + }; + + enum atscmh_sccc_code_mode { + ATSCMH_SCCC_CODE_HLF = 0, + ATSCMH_SCCC_CODE_QTR = 1, + ATSCMH_SCCC_CODE_RES = 2, + }; + + enum atscmh_rs_frame_ensemble { + ATSCMH_RSFRAME_ENS_PRI = 0, + ATSCMH_RSFRAME_ENS_SEC = 1, + }; + + enum atscmh_rs_frame_mode { + ATSCMH_RSFRAME_PRI_ONLY = 0, + ATSCMH_RSFRAME_PRI_SEC = 1, + ATSCMH_RSFRAME_RES = 2, + }; + + enum atscmh_rs_code_mode { + ATSCMH_RSCODE_211_187 = 0, + ATSCMH_RSCODE_223_187 = 1, + ATSCMH_RSCODE_235_187 = 2, + ATSCMH_RSCODE_RES = 3, + }; + + #define NO_STREAM_ID_FILTER (~0U) + #define LNA_AUTO (~0U) + + struct dtv_cmds_h { + char *name; /* A display name for debugging purposes */ + + __u32 cmd; /* A unique ID */ + + /* Flags */ + __u32 set:1; /* Either a set or get property */ + __u32 buffer:1; /* Does this property use the buffer? */ + __u32 reserved:30; /* Align */ + }; + + /** + * Scale types for the quality parameters. + * @FE_SCALE_NOT_AVAILABLE: That QoS measure is not available. That + * could indicate a temporary or a permanent + * condition. + * @FE_SCALE_DECIBEL: The scale is measured in 0.001 dB steps, typically + * used on signal measures. + * @FE_SCALE_RELATIVE: The scale is a relative percentual measure, + * ranging from 0 (0%) to 0xffff (100%). + * @FE_SCALE_COUNTER: The scale counts the occurrence of an event, like + * bit error, block error, lapsed time. + */ + enum fecap_scale_params { + FE_SCALE_NOT_AVAILABLE = 0, + FE_SCALE_DECIBEL, + FE_SCALE_RELATIVE, + FE_SCALE_COUNTER + }; + + /** + * struct dtv_stats - Used for reading a DTV status property + * + * @value: value of the measure. Should range from 0 to 0xffff; + * @scale: Filled with enum fecap_scale_params - the scale + * in usage for that parameter + * + * For most delivery systems, this will return a single value for each + * parameter. + * It should be noticed, however, that new OFDM delivery systems like + * ISDB can use different modulation types for each group of carriers. + * On such standards, up to 8 groups of statistics can be provided, one + * for each carrier group (called "layer" on ISDB). + * In order to be consistent with other delivery systems, the first + * value refers to the entire set of carriers ("global"). + * dtv_status:scale should use the value FE_SCALE_NOT_AVAILABLE when + * the value for the entire group of carriers or from one specific layer + * is not provided by the hardware. + * st.len should be filled with the latest filled status + 1. + * + * In other words, for ISDB, those values should be filled like: + * u.st.stat.svalue[0] = global statistics; + * u.st.stat.scale[0] = FE_SCALE_DECIBEL; + * u.st.stat.value[1] = layer A statistics; + * u.st.stat.scale[1] = FE_SCALE_NOT_AVAILABLE (if not available); + * u.st.stat.svalue[2] = layer B statistics; + * u.st.stat.scale[2] = FE_SCALE_DECIBEL; + * u.st.stat.svalue[3] = layer C statistics; + * u.st.stat.scale[3] = FE_SCALE_DECIBEL; + * u.st.len = 4; + */ + struct dtv_stats { + __u8 scale; /* enum fecap_scale_params type */ + union { + __u64 uvalue; /* for counters and relative scales */ + __s64 svalue; /* for 0.001 dB measures */ + }; + } __attribute__ ((packed)); + + + #define MAX_DTV_STATS 4 + + struct dtv_fe_stats { + __u8 len; + struct dtv_stats stat[MAX_DTV_STATS]; + } __attribute__ ((packed)); + + struct dtv_property { + __u32 cmd; + __u32 reserved[3]; + union { + __u32 data; + struct dtv_fe_stats st; + struct { + __u8 data[32]; + __u32 len; + __u32 reserved1[3]; + void *reserved2; + } buffer; + } u; + int result; + } __attribute__ ((packed)); + + /* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ + #define DTV_IOCTL_MAX_MSGS 64 + + struct dtv_properties { + __u32 num; + struct dtv_property *props; + }; + + #if defined(__DVB_CORE__) || !defined (__KERNEL__) + + /* + * DEPRECATED: The DVBv3 ioctls, structs and enums should not be used on + * newer programs, as it doesn't support the second generation of digital + * TV standards, nor supports newer delivery systems. + */ + + enum fe_bandwidth { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ, + BANDWIDTH_AUTO, + BANDWIDTH_5_MHZ, + BANDWIDTH_10_MHZ, + BANDWIDTH_1_712_MHZ, + }; + + /* This is needed for legacy userspace support */ + typedef enum fe_sec_voltage fe_sec_voltage_t; + typedef enum fe_caps fe_caps_t; + typedef enum fe_type fe_type_t; + typedef enum fe_sec_tone_mode fe_sec_tone_mode_t; + typedef enum fe_sec_mini_cmd fe_sec_mini_cmd_t; + typedef enum fe_status fe_status_t; + typedef enum fe_spectral_inversion fe_spectral_inversion_t; + typedef enum fe_code_rate fe_code_rate_t; + typedef enum fe_modulation fe_modulation_t; + typedef enum fe_transmit_mode fe_transmit_mode_t; + typedef enum fe_bandwidth fe_bandwidth_t; + typedef enum fe_guard_interval fe_guard_interval_t; + typedef enum fe_hierarchy fe_hierarchy_t; + typedef enum fe_pilot fe_pilot_t; + typedef enum fe_rolloff fe_rolloff_t; + typedef enum fe_delivery_system fe_delivery_system_t; + + struct dvb_qpsk_parameters { + __u32 symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + }; + + struct dvb_qam_parameters { + __u32 symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + fe_modulation_t modulation; /* modulation type (see above) */ + }; + + struct dvb_vsb_parameters { + fe_modulation_t modulation; /* modulation type (see above) */ + }; + + struct dvb_ofdm_parameters { + fe_bandwidth_t bandwidth; + fe_code_rate_t code_rate_HP; /* high priority stream code rate */ + fe_code_rate_t code_rate_LP; /* low priority stream code rate */ + fe_modulation_t constellation; /* modulation type (see above) */ + fe_transmit_mode_t transmission_mode; + fe_guard_interval_t guard_interval; + fe_hierarchy_t hierarchy_information; + }; + + struct dvb_frontend_parameters { + __u32 frequency; /* (absolute) frequency in Hz for DVB-C/DVB-T/ATSC */ + /* intermediate frequency in kHz for DVB-S */ + fe_spectral_inversion_t inversion; + union { + struct dvb_qpsk_parameters qpsk; /* DVB-S */ + struct dvb_qam_parameters qam; /* DVB-C */ + struct dvb_ofdm_parameters ofdm; /* DVB-T */ + struct dvb_vsb_parameters vsb; /* ATSC */ + } u; + }; + + struct dvb_frontend_event { + fe_status_t status; + struct dvb_frontend_parameters parameters; + }; + #endif + + #define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) + #define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) + + /** + * When set, this flag will disable any zigzagging or other "normal" tuning + * behaviour. Additionally, there will be no automatic monitoring of the lock + * status, and hence no frontend events will be generated. If a frontend device + * is closed, this flag will be automatically turned off when the device is + * reopened read-write. + */ + #define FE_TUNE_MODE_ONESHOT 0x01 + + #define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info) + + #define FE_DISEQC_RESET_OVERLOAD _IO('o', 62) + #define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd) + #define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply) + #define FE_DISEQC_SEND_BURST _IO('o', 65) /* fe_sec_mini_cmd_t */ + + #define FE_SET_TONE _IO('o', 66) /* fe_sec_tone_mode_t */ + #define FE_SET_VOLTAGE _IO('o', 67) /* fe_sec_voltage_t */ + #define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */ + + #define FE_READ_STATUS _IOR('o', 69, fe_status_t) + #define FE_READ_BER _IOR('o', 70, __u32) + #define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16) + #define FE_READ_SNR _IOR('o', 72, __u16) + #define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32) + + #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) + #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) + #define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */ + #define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) + + #define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ + + #endif /*_DVBFRONTEND_H_*/ + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/index.rst b/Documentation/linux_tv/index.rst new file mode 100644 index 000000000000..42b3d4520942 --- /dev/null +++ b/Documentation/linux_tv/index.rst @@ -0,0 +1,100 @@ +.. -*- coding: utf-8; mode: rst -*- + +############################## +LINUX MEDIA INFRASTRUCTURE API +############################## + +**Copyright** 2009-2015 : LinuxTV Developers + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation. A copy of +the license is included in the chapter entitled "GNU Free Documentation +License" + + +============ +Introduction +============ + +This document covers the Linux Kernel to Userspace API's used by video +and radio streaming devices, including video cameras, analog and digital +TV receiver cards, AM/FM receiver cards, streaming capture and output +devices, codec devices and remote controllers. + +A typical media device hardware is shown at +:ref:`typical_media_device`. + + +.. _typical_media_device: + +.. figure:: media_api_files/typical_media_device.* + :alt: typical_media_device.svg + :align: center + + Typical Media Device + + Typical Media Device Block Diagram + + + +The media infrastructure API was designed to control such devices. It is +divided into four parts. + +The first part covers radio, video capture and output, cameras, analog +TV devices and codecs. + +The second part covers the API used for digital TV and Internet +reception via one of the several digital tv standards. While it is +called as DVB API, in fact it covers several different video standards +including DVB-T/T2, DVB-S/S2, DVB-C, ATSC, ISDB-T, ISDB-S,etc. The +complete list of supported standards can be found at +:ref:`fe-delivery-system-t`. + +The third part covers the Remote Controller API. + +The fourth part covers the Media Controller API. + +It should also be noted that a media device may also have audio +components, like mixers, PCM capture, PCM playback, etc, which are +controlled via ALSA API. + +For additional information and for the latest development code, see: +`https://linuxtv.org `__. + +For discussing improvements, reporting troubles, sending new drivers, +etc, please mail to: +`Linux Media Mailing List (LMML). `__. + + +.. toctree:: + :maxdepth: 1 + + media/v4l/v4l2 + media/dvb/dvbapi + media/v4l/remote_controllers + media/v4l/media-controller + media/v4l/gen-errors + media/v4l/fdl-appendix + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ + + +.. only:: html + + Retrieval + ========= + + * :ref:`genindex` + +.. todolist:: + diff --git a/Documentation/linux_tv/media/dvb/FE_DISHNETWORK_SEND_LEGACY_CMD.rst b/Documentation/linux_tv/media/dvb/FE_DISHNETWORK_SEND_LEGACY_CMD.rst new file mode 100644 index 000000000000..f4effaab9a1a --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_DISHNETWORK_SEND_LEGACY_CMD.rst @@ -0,0 +1,55 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_DISHNETWORK_SEND_LEGACY_CMD: + +****************************** +FE_DISHNETWORK_SEND_LEGACY_CMD +****************************** + +DESCRIPTION + +WARNING: This is a very obscure legacy command, used only at stv0299 +driver. Should not be used on newer drivers. + +It provides a non-standard method for selecting Diseqc voltage on the +frontend, for Dish Network legacy switches. + +As support for this ioctl were added in 2004, this means that such +dishes were already legacy in 2004. + +SYNOPSIS + +int ioctl(int fd, int request = +:ref:`FE_DISHNETWORK_SEND_LEGACY_CMD `, +unsigned long cmd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - unsigned long cmd + + - sends the specified raw cmd to the dish via DISEqC. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_GET_EVENT.rst b/Documentation/linux_tv/media/dvb/FE_GET_EVENT.rst new file mode 100644 index 000000000000..75eab893c184 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_GET_EVENT.rst @@ -0,0 +1,89 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_GET_EVENT: + +************ +FE_GET_EVENT +************ + +DESCRIPTION + +This ioctl call returns a frontend event if available. If an event is +not available, the behavior depends on whether the device is in blocking +or non-blocking mode. In the latter case, the call fails immediately +with errno set to EWOULDBLOCK. In the former case, the call blocks until +an event becomes available. + +SYNOPSIS + +int ioctl(int fd, int request = QPSK_GET_EVENT, struct +dvb_frontend_event *ev); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals :ref:`FE_GET_EVENT ` for this command. + + - .. row 3 + + - struct dvb_frontend_event *ev + + - Points to the location where the event, + + - .. row 4 + + - + - if any, is to be stored. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EWOULDBLOCK + + - There is no event pending, and the device is in non-blocking mode. + + - .. row 2 + + - EOVERFLOW + + - Overflow in event queue - one or more events were lost. + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_GET_FRONTEND.rst b/Documentation/linux_tv/media/dvb/FE_GET_FRONTEND.rst new file mode 100644 index 000000000000..30c85cf0423c --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_GET_FRONTEND.rst @@ -0,0 +1,77 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_GET_FRONTEND: + +*************** +FE_GET_FRONTEND +*************** + +DESCRIPTION + +This ioctl call queries the currently effective frontend parameters. For +this command, read-only access to the device is sufficient. + +SYNOPSIS + +int ioctl(int fd, int request = +:ref:`FE_GET_FRONTEND `, struct +dvb_frontend_parameters *p); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals :ref:`FE_SET_FRONTEND ` for this + command. + + - .. row 3 + + - struct dvb_frontend_parameters *p + + - Points to parameters for tuning operation. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - Maximum supported symbol rate reached. + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_READ_BER.rst b/Documentation/linux_tv/media/dvb/FE_READ_BER.rst new file mode 100644 index 000000000000..e21451886dc2 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_READ_BER.rst @@ -0,0 +1,61 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_READ_BER: + +*********** +FE_READ_BER +*********** + +DESCRIPTION + +This ioctl call returns the bit error rate for the signal currently +received/demodulated by the front-end. For this command, read-only +access to the device is sufficient. + +SYNOPSIS + +int ioctl(int fd, int request = :ref:`FE_READ_BER `, +uint32_t *ber); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals :ref:`FE_READ_BER ` for this command. + + - .. row 3 + + - uint32_t *ber + + - The bit error rate is stored into *ber. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_READ_SIGNAL_STRENGTH.rst b/Documentation/linux_tv/media/dvb/FE_READ_SIGNAL_STRENGTH.rst new file mode 100644 index 000000000000..3e34bea21b6c --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_READ_SIGNAL_STRENGTH.rst @@ -0,0 +1,64 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_READ_SIGNAL_STRENGTH: + +*********************** +FE_READ_SIGNAL_STRENGTH +*********************** + +DESCRIPTION + +This ioctl call returns the signal strength value for the signal +currently received by the front-end. For this command, read-only access +to the device is sufficient. + +SYNOPSIS + +int ioctl( int fd, int request = +:ref:`FE_READ_SIGNAL_STRENGTH `, +uint16_t *strength); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals + :ref:`FE_READ_SIGNAL_STRENGTH ` + for this command. + + - .. row 3 + + - uint16_t *strength + + - The signal strength value is stored into *strength. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_READ_SNR.rst b/Documentation/linux_tv/media/dvb/FE_READ_SNR.rst new file mode 100644 index 000000000000..b8a639706e9e --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_READ_SNR.rst @@ -0,0 +1,61 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_READ_SNR: + +*********** +FE_READ_SNR +*********** + +DESCRIPTION + +This ioctl call returns the signal-to-noise ratio for the signal +currently received by the front-end. For this command, read-only access +to the device is sufficient. + +SYNOPSIS + +int ioctl(int fd, int request = :ref:`FE_READ_SNR `, +uint16_t *snr); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals :ref:`FE_READ_SNR ` for this command. + + - .. row 3 + + - uint16_t *snr + + - The signal-to-noise ratio is stored into *snr. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_READ_UNCORRECTED_BLOCKS.rst b/Documentation/linux_tv/media/dvb/FE_READ_UNCORRECTED_BLOCKS.rst new file mode 100644 index 000000000000..261eb20ddadf --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_READ_UNCORRECTED_BLOCKS.rst @@ -0,0 +1,66 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_READ_UNCORRECTED_BLOCKS: + +************************** +FE_READ_UNCORRECTED_BLOCKS +************************** + +DESCRIPTION + +This ioctl call returns the number of uncorrected blocks detected by the +device driver during its lifetime. For meaningful measurements, the +increment in block count during a specific time interval should be +calculated. For this command, read-only access to the device is +sufficient. + +SYNOPSIS + +int ioctl( int fd, int request = +:ref:`FE_READ_UNCORRECTED_BLOCKS `, +uint32_t *ublocks); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals + :ref:`FE_READ_UNCORRECTED_BLOCKS ` + for this command. + + - .. row 3 + + - uint32_t *ublocks + + - The total number of uncorrected blocks seen by the driver so far. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/FE_SET_FRONTEND.rst b/Documentation/linux_tv/media/dvb/FE_SET_FRONTEND.rst new file mode 100644 index 000000000000..885f9e3ceb59 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/FE_SET_FRONTEND.rst @@ -0,0 +1,84 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_SET_FRONTEND: + +*************** +FE_SET_FRONTEND +*************** + +DESCRIPTION + +This ioctl call starts a tuning operation using specified parameters. +The result of this call will be successful if the parameters were valid +and the tuning could be initiated. The result of the tuning operation in +itself, however, will arrive asynchronously as an event (see +documentation for :ref:`FE_GET_EVENT ` and +FrontendEvent.) If a new :ref:`FE_SET_FRONTEND ` +operation is initiated before the previous one was completed, the +previous operation will be aborted in favor of the new one. This command +requires read/write access to the device. + +SYNOPSIS + +int ioctl(int fd, int request = +:ref:`FE_SET_FRONTEND `, struct +dvb_frontend_parameters *p); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals :ref:`FE_SET_FRONTEND ` for this + command. + + - .. row 3 + + - struct dvb_frontend_parameters *p + + - Points to parameters for tuning operation. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - Maximum supported symbol rate reached. + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/audio.rst b/Documentation/linux_tv/media/dvb/audio.rst new file mode 100644 index 000000000000..d6b6f9edf3b3 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/audio.rst @@ -0,0 +1,37 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_audio: + +################ +DVB Audio Device +################ +The DVB audio device controls the MPEG2 audio decoder of the DVB +hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data +types and and ioctl definitions can be accessed by including +``linux/dvb/audio.h`` in your application. + +Please note that some DVB cards don’t have their own MPEG decoder, which +results in the omission of the audio and video device. + +These ioctls were also used by V4L2 to control MPEG decoders implemented +in V4L2. The use of these ioctls for that purpose has been made obsolete +and proper V4L2 ioctls or controls have been created to replace that +functionality. + + +.. toctree:: + :maxdepth: 1 + + audio_data_types + audio_function_calls + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/audio_data_types.rst b/Documentation/linux_tv/media/dvb/audio_data_types.rst new file mode 100644 index 000000000000..b3f5aa0ac6e4 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/audio_data_types.rst @@ -0,0 +1,187 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _audio_data_types: + +**************** +Audio Data Types +**************** + +This section describes the structures, data types and defines used when +talking to the audio device. + + +.. _audio-stream-source-t: + +audio_stream_source_t +===================== + +The audio stream source is set through the AUDIO_SELECT_SOURCE call +and can take the following values, depending on whether we are replaying +from an internal (demux) or external (user write) source. + + +.. code-block:: c + + typedef enum { + AUDIO_SOURCE_DEMUX, + AUDIO_SOURCE_MEMORY + } audio_stream_source_t; + +AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the +frontend or the DVR device) as the source of the video stream. If +AUDIO_SOURCE_MEMORY is selected the stream comes from the application +through the ``write()`` system call. + + +.. _audio-play-state-t: + +audio_play_state_t +================== + +The following values can be returned by the AUDIO_GET_STATUS call +representing the state of audio playback. + + +.. code-block:: c + + typedef enum { + AUDIO_STOPPED, + AUDIO_PLAYING, + AUDIO_PAUSED + } audio_play_state_t; + + +.. _audio-channel-select-t: + +audio_channel_select_t +====================== + +The audio channel selected via AUDIO_CHANNEL_SELECT is determined by +the following values. + + +.. code-block:: c + + typedef enum { + AUDIO_STEREO, + AUDIO_MONO_LEFT, + AUDIO_MONO_RIGHT, + AUDIO_MONO, + AUDIO_STEREO_SWAPPED + } audio_channel_select_t; + + +.. _audio-status: + +struct audio_status +=================== + +The AUDIO_GET_STATUS call returns the following structure informing +about various states of the playback operation. + + +.. code-block:: c + + typedef struct audio_status { + boolean AV_sync_state; + boolean mute_state; + audio_play_state_t play_state; + audio_stream_source_t stream_source; + audio_channel_select_t channel_select; + boolean bypass_mode; + audio_mixer_t mixer_state; + } audio_status_t; + + +.. _audio-mixer: + +struct audio_mixer +================== + +The following structure is used by the AUDIO_SET_MIXER call to set the +audio volume. + + +.. code-block:: c + + typedef struct audio_mixer { + unsigned int volume_left; + unsigned int volume_right; + } audio_mixer_t; + + +.. _audio_encodings: + +audio encodings +=============== + +A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the +following bits set according to the hardwares capabilities. + + +.. code-block:: c + + #define AUDIO_CAP_DTS 1 + #define AUDIO_CAP_LPCM 2 + #define AUDIO_CAP_MP1 4 + #define AUDIO_CAP_MP2 8 + #define AUDIO_CAP_MP3 16 + #define AUDIO_CAP_AAC 32 + #define AUDIO_CAP_OGG 64 + #define AUDIO_CAP_SDDS 128 + #define AUDIO_CAP_AC3 256 + + +.. _audio-karaoke: + +struct audio_karaoke +==================== + +The ioctl AUDIO_SET_KARAOKE uses the following format: + + +.. code-block:: c + + typedef + struct audio_karaoke { + int vocal1; + int vocal2; + int melody; + } audio_karaoke_t; + +If Vocal1 or Vocal2 are non-zero, they get mixed into left and right t +at 70% each. If both, Vocal1 and Vocal2 are non-zero, Vocal1 gets mixed +into the left channel and Vocal2 into the right channel at 100% each. Ff +Melody is non-zero, the melody channel gets mixed into left and right. + + +.. _audio-attributes-t: + +audio attributes +================ + +The following attributes can be set by a call to AUDIO_SET_ATTRIBUTES: + + +.. code-block:: c + + typedef uint16_t audio_attributes_t; + /* bits: descr. */ + /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ + /* 12 multichannel extension */ + /* 11-10 audio type (0=not spec, 1=language included) */ + /* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ + /* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */ + /* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ + /* 2- 0 number of audio channels (n+1 channels) */ + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/audio_function_calls.rst b/Documentation/linux_tv/media/dvb/audio_function_calls.rst new file mode 100644 index 000000000000..41a5757ffd72 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/audio_function_calls.rst @@ -0,0 +1,1308 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _audio_function_calls: + +******************** +Audio Function Calls +******************** + + +.. _audio_fopen: + +open() +====== + +DESCRIPTION + +This system call opens a named audio device (e.g. +/dev/dvb/adapter0/audio0) for subsequent use. When an open() call has +succeeded, the device will be ready for use. The significance of +blocking or non-blocking mode is described in the documentation for +functions where there is a difference. It does not affect the semantics +of the open() call itself. A device opened in blocking mode can later be +put into non-blocking mode (and vice versa) using the F_SETFL command +of the fcntl system call. This is a standard system call, documented in +the Linux manual page for fcntl. Only one user can open the Audio Device +in O_RDWR mode. All other attempts to open the device in this mode will +fail, and an error code will be returned. If the Audio Device is opened +in O_RDONLY mode, the only ioctl call that can be used is +AUDIO_GET_STATUS. All other call will return with an error code. + +SYNOPSIS + +int open(const char *deviceName, int flags); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - const char *deviceName + + - Name of specific audio device. + + - .. row 2 + + - int flags + + - A bit-wise OR of the following flags: + + - .. row 3 + + - + - O_RDONLY read-only access + + - .. row 4 + + - + - O_RDWR read/write access + + - .. row 5 + + - + - O_NONBLOCK open in non-blocking mode + + - .. row 6 + + - + - (blocking mode is the default) + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - ENODEV + + - Device driver not loaded/available. + + - .. row 2 + + - EBUSY + + - Device or resource busy. + + - .. row 3 + + - EINVAL + + - Invalid argument. + + + +.. _audio_fclose: + +close() +======= + +DESCRIPTION + +This system call closes a previously opened audio device. + +SYNOPSIS + +int close(int fd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _audio_fwrite: + +write() +======= + +DESCRIPTION + +This system call can only be used if AUDIO_SOURCE_MEMORY is selected +in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in +PES format. If O_NONBLOCK is not specified the function will block +until buffer space is available. The amount of data to be transferred is +implied by count. + +SYNOPSIS + +size_t write(int fd, const void *buf, size_t count); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - void *buf + + - Pointer to the buffer containing the PES data. + + - .. row 3 + + - size_t count + + - Size of buf. + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EPERM + + - Mode AUDIO_SOURCE_MEMORY not selected. + + - .. row 2 + + - ENOMEM + + - Attempted to write more data than the internal buffer can hold. + + - .. row 3 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _AUDIO_STOP: + +AUDIO_STOP +========== + +DESCRIPTION + +This ioctl call asks the Audio Device to stop playing the current +stream. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_STOP); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_STOP for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_PLAY: + +AUDIO_PLAY +========== + +DESCRIPTION + +This ioctl call asks the Audio Device to start playing an audio stream +from the selected source. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_PLAY); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_PLAY for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_PAUSE: + +AUDIO_PAUSE +=========== + +DESCRIPTION + +This ioctl call suspends the audio stream being played. Decoding and +playing are paused. It is then possible to restart again decoding and +playing process of the audio stream using AUDIO_CONTINUE command. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_PAUSE); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_PAUSE for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_CONTINUE: + +AUDIO_CONTINUE +============== + +DESCRIPTION + +This ioctl restarts the decoding and playing process previously paused +with AUDIO_PAUSE command. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_CONTINUE); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_CONTINUE for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SELECT_SOURCE: + +AUDIO_SELECT_SOURCE +=================== + +DESCRIPTION + +This ioctl call informs the audio device which source shall be used for +the input data. The possible sources are demux or memory. If +AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device +through the write command. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_SELECT_SOURCE, +audio_stream_source_t source); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SELECT_SOURCE for this command. + + - .. row 3 + + - audio_stream_source_t source + + - Indicates the source that shall be used for the Audio stream. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SET_MUTE: + +AUDIO_SET_MUTE +============== + +DESCRIPTION + +This ioctl is for DVB devices only. To control a V4L2 decoder use the +V4L2 :ref:`VIDIOC_DECODER_CMD ` with the +``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead. + +This ioctl call asks the audio device to mute the stream that is +currently being played. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_SET_MUTE, boolean state); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_MUTE for this command. + + - .. row 3 + + - boolean state + + - Indicates if audio device shall mute or not. + + - .. row 4 + + - + - TRUE Audio Mute + + - .. row 5 + + - + - FALSE Audio Un-mute + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SET_AV_SYNC: + +AUDIO_SET_AV_SYNC +================= + +DESCRIPTION + +This ioctl call asks the Audio Device to turn ON or OFF A/V +synchronization. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_SET_AV_SYNC, boolean state); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_AV_SYNC for this command. + + - .. row 3 + + - boolean state + + - Tells the DVB subsystem if A/V synchronization shall be ON or OFF. + + - .. row 4 + + - + - TRUE AV-sync ON + + - .. row 5 + + - + - FALSE AV-sync OFF + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SET_BYPASS_MODE: + +AUDIO_SET_BYPASS_MODE +===================== + +DESCRIPTION + +This ioctl call asks the Audio Device to bypass the Audio decoder and +forward the stream without decoding. This mode shall be used if streams +that can’t be handled by the DVB system shall be decoded. Dolby +DigitalTM streams are automatically forwarded by the DVB subsystem if +the hardware can handle it. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_SET_BYPASS_MODE, boolean mode); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_BYPASS_MODE for this command. + + - .. row 3 + + - boolean mode + + - Enables or disables the decoding of the current Audio stream in + the DVB subsystem. + + - .. row 4 + + - + - TRUE Bypass is disabled + + - .. row 5 + + - + - FALSE Bypass is enabled + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_CHANNEL_SELECT: + +AUDIO_CHANNEL_SELECT +==================== + +DESCRIPTION + +This ioctl is for DVB devices only. To control a V4L2 decoder use the +V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead. + +This ioctl call asks the Audio Device to select the requested channel if +possible. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_CHANNEL_SELECT, +audio_channel_select_t); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_CHANNEL_SELECT for this command. + + - .. row 3 + + - audio_channel_select_t ch + + - Select the output format of the audio (mono left/right, stereo). + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_BILINGUAL_CHANNEL_SELECT: + +AUDIO_BILINGUAL_CHANNEL_SELECT +============================== + +DESCRIPTION + +This ioctl is obsolete. Do not use in new drivers. It has been replaced +by the V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK`` control +for MPEG decoders controlled through V4L2. + +This ioctl call asks the Audio Device to select the requested channel +for bilingual streams if possible. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_BILINGUAL_CHANNEL_SELECT, +audio_channel_select_t); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_BILINGUAL_CHANNEL_SELECT for this command. + + - .. row 3 + + - audio_channel_select_t ch + + - Select the output format of the audio (mono left/right, stereo). + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_GET_PTS: + +AUDIO_GET_PTS +============= + +DESCRIPTION + +This ioctl is obsolete. Do not use in new drivers. If you need this +functionality, then please contact the linux-media mailing list +(`https://linuxtv.org/lists.php `__). + +This ioctl call asks the Audio Device to return the current PTS +timestamp. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_GET_PTS, __u64 *pts); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_GET_PTS for this command. + + - .. row 3 + + - __u64 *pts + + - Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 / + ISO/IEC 13818-1. + + The PTS should belong to the currently played frame if possible, + but may also be a value close to it like the PTS of the last + decoded frame or the last PTS extracted by the PES parser. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_GET_STATUS: + +AUDIO_GET_STATUS +================ + +DESCRIPTION + +This ioctl call asks the Audio Device to return the current state of the +Audio Device. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_GET_STATUS, struct audio_status +*status); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_GET_STATUS for this command. + + - .. row 3 + + - struct audio_status *status + + - Returns the current state of Audio Device. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_GET_CAPABILITIES: + +AUDIO_GET_CAPABILITIES +====================== + +DESCRIPTION + +This ioctl call asks the Audio Device to tell us about the decoding +capabilities of the audio hardware. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_GET_CAPABILITIES, unsigned int +*cap); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_GET_CAPABILITIES for this command. + + - .. row 3 + + - unsigned int *cap + + - Returns a bit array of supported sound formats. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_CLEAR_BUFFER: + +AUDIO_CLEAR_BUFFER +================== + +DESCRIPTION + +This ioctl call asks the Audio Device to clear all software and hardware +buffers of the audio decoder device. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_CLEAR_BUFFER); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_CLEAR_BUFFER for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SET_ID: + +AUDIO_SET_ID +============ + +DESCRIPTION + +This ioctl selects which sub-stream is to be decoded if a program or +system stream is sent to the video device. If no audio stream type is +set the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for +AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow for +other stream types. If the stream type is set the id just specifies the +substream id of the audio stream and only the first 5 bits are +recognized. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_SET_ID, int id); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_ID for this command. + + - .. row 3 + + - int id + + - audio sub-stream id + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SET_MIXER: + +AUDIO_SET_MIXER +=============== + +DESCRIPTION + +This ioctl lets you adjust the mixer settings of the audio decoder. + +SYNOPSIS + +int ioctl(int fd, int request = AUDIO_SET_MIXER, audio_mixer_t +*mix); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_ID for this command. + + - .. row 3 + + - audio_mixer_t *mix + + - mixer settings. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _AUDIO_SET_STREAMTYPE: + +AUDIO_SET_STREAMTYPE +==================== + +DESCRIPTION + +This ioctl tells the driver which kind of audio stream to expect. This +is useful if the stream offers several audio sub-streams like LPCM and +AC3. + +SYNOPSIS + +int ioctl(fd, int request = AUDIO_SET_STREAMTYPE, int type); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_STREAMTYPE for this command. + + - .. row 3 + + - int type + + - stream type + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - type is not a valid or supported stream type. + + + +.. _AUDIO_SET_EXT_ID: + +AUDIO_SET_EXT_ID +================ + +DESCRIPTION + +This ioctl can be used to set the extension id for MPEG streams in DVD +playback. Only the first 3 bits are recognized. + +SYNOPSIS + +int ioctl(fd, int request = AUDIO_SET_EXT_ID, int id); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_EXT_ID for this command. + + - .. row 3 + + - int id + + - audio sub_stream_id + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - id is not a valid id. + + + +.. _AUDIO_SET_ATTRIBUTES: + +AUDIO_SET_ATTRIBUTES +==================== + +DESCRIPTION + +This ioctl is intended for DVD playback and allows you to set certain +information about the audio stream. + +SYNOPSIS + +int ioctl(fd, int request = AUDIO_SET_ATTRIBUTES, audio_attributes_t +attr ); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_ATTRIBUTES for this command. + + - .. row 3 + + - audio_attributes_t attr + + - audio attributes according to section ?? + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - attr is not a valid or supported attribute setting. + + + +.. _AUDIO_SET_KARAOKE: + +AUDIO_SET_KARAOKE +================= + +DESCRIPTION + +This ioctl allows one to set the mixer settings for a karaoke DVD. + +SYNOPSIS + +int ioctl(fd, int request = AUDIO_SET_KARAOKE, audio_karaoke_t +*karaoke); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals AUDIO_SET_KARAOKE for this command. + + - .. row 3 + + - audio_karaoke_t *karaoke + + - karaoke settings according to section ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - karaoke is not a valid or supported karaoke setting. + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/audio_h.rst b/Documentation/linux_tv/media/dvb/audio_h.rst new file mode 100644 index 000000000000..09a73a54ab00 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/audio_h.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _audio_h: + +********************* +DVB Audio Header File +********************* + + +.. toctree:: + :maxdepth: 1 + + ../../audio.h + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/ca.rst b/Documentation/linux_tv/media/dvb/ca.rst new file mode 100644 index 000000000000..bb01d93f0256 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/ca.rst @@ -0,0 +1,29 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_ca: + +############# +DVB CA Device +############# +The DVB CA device controls the conditional access hardware. It can be +accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl +definitions can be accessed by including ``linux/dvb/ca.h`` in your +application. + + +.. toctree:: + :maxdepth: 1 + + ca_data_types + ca_function_calls + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/ca_data_types.rst b/Documentation/linux_tv/media/dvb/ca_data_types.rst new file mode 100644 index 000000000000..bb0cdfa7c9a6 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/ca_data_types.rst @@ -0,0 +1,121 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _ca_data_types: + +************* +CA Data Types +************* + + +.. _ca-slot-info: + +ca_slot_info_t +============== + + +.. code-block:: c + + typedef struct ca_slot_info { + int num; /* slot number */ + + int type; /* CA interface this slot supports */ + #define CA_CI 1 /* CI high level interface */ + #define CA_CI_LINK 2 /* CI link layer level interface */ + #define CA_CI_PHYS 4 /* CI physical layer level interface */ + #define CA_DESCR 8 /* built-in descrambler */ + #define CA_SC 128 /* simple smart card interface */ + + unsigned int flags; + #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ + #define CA_CI_MODULE_READY 2 + } ca_slot_info_t; + + +.. _ca-descr-info: + +ca_descr_info_t +=============== + + +.. code-block:: c + + typedef struct ca_descr_info { + unsigned int num; /* number of available descramblers (keys) */ + unsigned int type; /* type of supported scrambling system */ + #define CA_ECD 1 + #define CA_NDS 2 + #define CA_DSS 4 + } ca_descr_info_t; + + +.. _ca-caps: + +ca_caps_t +========= + + +.. code-block:: c + + typedef struct ca_caps { + unsigned int slot_num; /* total number of CA card and module slots */ + unsigned int slot_type; /* OR of all supported types */ + unsigned int descr_num; /* total number of descrambler slots (keys) */ + unsigned int descr_type;/* OR of all supported types */ + } ca_cap_t; + + +.. _ca-msg: + +ca_msg_t +======== + + +.. code-block:: c + + /* a message to/from a CI-CAM */ + typedef struct ca_msg { + unsigned int index; + unsigned int type; + unsigned int length; + unsigned char msg[256]; + } ca_msg_t; + + +.. _ca-descr: + +ca_descr_t +========== + + +.. code-block:: c + + typedef struct ca_descr { + unsigned int index; + unsigned int parity; + unsigned char cw[8]; + } ca_descr_t; + + +.. _ca-pid: + +ca-pid +====== + + +.. code-block:: c + + typedef struct ca_pid { + unsigned int pid; + int index; /* -1 == disable*/ + } ca_pid_t; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/ca_function_calls.rst b/Documentation/linux_tv/media/dvb/ca_function_calls.rst new file mode 100644 index 000000000000..9984b355f48f --- /dev/null +++ b/Documentation/linux_tv/media/dvb/ca_function_calls.rst @@ -0,0 +1,541 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _ca_function_calls: + +***************** +CA Function Calls +***************** + + +.. _ca_fopen: + +open() +====== + +DESCRIPTION + +This system call opens a named ca device (e.g. /dev/ost/ca) for +subsequent use. + +When an open() call has succeeded, the device will be ready for use. The +significance of blocking or non-blocking mode is described in the +documentation for functions where there is a difference. It does not +affect the semantics of the open() call itself. A device opened in +blocking mode can later be put into non-blocking mode (and vice versa) +using the F_SETFL command of the fcntl system call. This is a standard +system call, documented in the Linux manual page for fcntl. Only one +user can open the CA Device in O_RDWR mode. All other attempts to open +the device in this mode will fail, and an error code will be returned. + +SYNOPSIS + +int open(const char *deviceName, int flags); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - const char *deviceName + + - Name of specific video device. + + - .. row 2 + + - int flags + + - A bit-wise OR of the following flags: + + - .. row 3 + + - + - O_RDONLY read-only access + + - .. row 4 + + - + - O_RDWR read/write access + + - .. row 5 + + - + - O_NONBLOCK open in non-blocking mode + + - .. row 6 + + - + - (blocking mode is the default) + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - ENODEV + + - Device driver not loaded/available. + + - .. row 2 + + - EINTERNAL + + - Internal error. + + - .. row 3 + + - EBUSY + + - Device or resource busy. + + - .. row 4 + + - EINVAL + + - Invalid argument. + + + +.. _ca_fclose: + +close() +======= + +DESCRIPTION + +This system call closes a previously opened audio device. + +SYNOPSIS + +int close(int fd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _CA_RESET: + +CA_RESET +======== + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_RESET); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_RESET for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_GET_CAP: + +CA_GET_CAP +========== + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_GET_CAP, ca_caps_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_GET_CAP for this command. + + - .. row 3 + + - ca_caps_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_GET_SLOT_INFO: + +CA_GET_SLOT_INFO +================ + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_GET_SLOT_INFO, ca_slot_info_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_GET_SLOT_INFO for this command. + + - .. row 3 + + - ca_slot_info_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_GET_DESCR_INFO: + +CA_GET_DESCR_INFO +================= + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_GET_DESCR_INFO, ca_descr_info_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_GET_DESCR_INFO for this command. + + - .. row 3 + + - ca_descr_info_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_GET_MSG: + +CA_GET_MSG +========== + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_GET_MSG, ca_msg_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_GET_MSG for this command. + + - .. row 3 + + - ca_msg_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_SEND_MSG: + +CA_SEND_MSG +=========== + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_SEND_MSG, ca_msg_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_SEND_MSG for this command. + + - .. row 3 + + - ca_msg_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_SET_DESCR: + +CA_SET_DESCR +============ + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_SET_DESCR, ca_descr_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_SET_DESCR for this command. + + - .. row 3 + + - ca_descr_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _CA_SET_PID: + +CA_SET_PID +========== + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = CA_SET_PID, ca_pid_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals CA_SET_PID for this command. + + - .. row 3 + + - ca_pid_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/ca_h.rst b/Documentation/linux_tv/media/dvb/ca_h.rst new file mode 100644 index 000000000000..229bfbca045b --- /dev/null +++ b/Documentation/linux_tv/media/dvb/ca_h.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _ca_h: + +********************************** +DVB Conditional Access Header File +********************************** + + +.. toctree:: + :maxdepth: 1 + + ../../ca.h + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/demux.rst b/Documentation/linux_tv/media/dvb/demux.rst new file mode 100644 index 000000000000..3bcee72c68fb --- /dev/null +++ b/Documentation/linux_tv/media/dvb/demux.rst @@ -0,0 +1,29 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_demux: + +################ +DVB Demux Device +################ +The DVB demux device controls the filters of the DVB hardware/software. +It can be accessed through ``/dev/adapter?/demux?``. Data types and and +ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in +your application. + + +.. toctree:: + :maxdepth: 1 + + dmx_types + dmx_fcalls + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dmx_fcalls.rst b/Documentation/linux_tv/media/dvb/dmx_fcalls.rst new file mode 100644 index 000000000000..5982b57f0a3b --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dmx_fcalls.rst @@ -0,0 +1,1013 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dmx_fcalls: + +******************** +Demux Function Calls +******************** + + +.. _dmx_fopen: + +open() +====== + +DESCRIPTION + +This system call, used with a device name of /dev/dvb/adapter0/demux0, +allocates a new filter and returns a handle which can be used for +subsequent control of that filter. This call has to be made for each +filter to be used, i.e. every returned file descriptor is a reference to +a single filter. /dev/dvb/adapter0/dvr0 is a logical device to be used +for retrieving Transport Streams for digital video recording. When +reading from this device a transport stream containing the packets from +all PES filters set in the corresponding demux device +(/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A +recorded Transport Stream is replayed by writing to this device. + +The significance of blocking or non-blocking mode is described in the +documentation for functions where there is a difference. It does not +affect the semantics of the open() call itself. A device opened in +blocking mode can later be put into non-blocking mode (and vice versa) +using the F_SETFL command of the fcntl system call. + +SYNOPSIS + +int open(const char *deviceName, int flags); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - const char *deviceName + + - Name of demux device. + + - .. row 2 + + - int flags + + - A bit-wise OR of the following flags: + + - .. row 3 + + - + - O_RDWR read/write access + + - .. row 4 + + - + - O_NONBLOCK open in non-blocking mode + + - .. row 5 + + - + - (blocking mode is the default) + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - ENODEV + + - Device driver not loaded/available. + + - .. row 2 + + - EINVAL + + - Invalid argument. + + - .. row 3 + + - EMFILE + + - “Too many open files”, i.e. no more filters available. + + - .. row 4 + + - ENOMEM + + - The driver failed to allocate enough memory. + + + +.. _dmx_fclose: + +close() +======= + +DESCRIPTION + +This system call deactivates and deallocates a filter that was +previously allocated via the open() call. + +SYNOPSIS + +int close(int fd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _dmx_fread: + +read() +====== + +DESCRIPTION + +This system call returns filtered data, which might be section or PES +data. The filtered data is transferred from the driver’s internal +circular buffer to buf. The maximum amount of data to be transferred is +implied by count. + +SYNOPSIS + +size_t read(int fd, void *buf, size_t count); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - void *buf + + - Pointer to the buffer to be used for returned filtered data. + + - .. row 3 + + - size_t count + + - Size of buf. + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EWOULDBLOCK + + - No data to return and O_NONBLOCK was specified. + + - .. row 2 + + - EBADF + + - fd is not a valid open file descriptor. + + - .. row 3 + + - ECRC + + - Last section had a CRC error - no data returned. The buffer is + flushed. + + - .. row 4 + + - EOVERFLOW + + - + + - .. row 5 + + - + - The filtered data was not read from the buffer in due time, + resulting in non-read data being lost. The buffer is flushed. + + - .. row 6 + + - ETIMEDOUT + + - The section was not loaded within the stated timeout period. See + ioctl DMX_SET_FILTER for how to set a timeout. + + - .. row 7 + + - EFAULT + + - The driver failed to write to the callers buffer due to an invalid + *buf pointer. + + + +.. _dmx_fwrite: + +write() +======= + +DESCRIPTION + +This system call is only provided by the logical device +/dev/dvb/adapter0/dvr0, associated with the physical demux device that +provides the actual DVR functionality. It is used for replay of a +digitally recorded Transport Stream. Matching filters have to be defined +in the corresponding physical demux device, /dev/dvb/adapter0/demux0. +The amount of data to be transferred is implied by count. + +SYNOPSIS + +ssize_t write(int fd, const void *buf, size_t count); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - void *buf + + - Pointer to the buffer containing the Transport Stream. + + - .. row 3 + + - size_t count + + - Size of buf. + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EWOULDBLOCK + + - No data was written. This might happen if O_NONBLOCK was + specified and there is no more buffer space available (if + O_NONBLOCK is not specified the function will block until buffer + space is available). + + - .. row 2 + + - EBUSY + + - This error code indicates that there are conflicting requests. The + corresponding demux device is setup to receive data from the + front- end. Make sure that these filters are stopped and that the + filters with input set to DMX_IN_DVR are started. + + - .. row 3 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _DMX_START: + +DMX_START +========= + +DESCRIPTION + +This ioctl call is used to start the actual filtering operation defined +via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER. + +SYNOPSIS + +int ioctl( int fd, int request = DMX_START); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_START for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - Invalid argument, i.e. no filtering parameters provided via the + DMX_SET_FILTER or DMX_SET_PES_FILTER functions. + + - .. row 2 + + - EBUSY + + - This error code indicates that there are conflicting requests. + There are active filters filtering data from another input source. + Make sure that these filters are stopped before starting this + filter. + + + +.. _DMX_STOP: + +DMX_STOP +======== + +DESCRIPTION + +This ioctl call is used to stop the actual filtering operation defined +via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and +started via the DMX_START command. + +SYNOPSIS + +int ioctl( int fd, int request = DMX_STOP); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_STOP for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_SET_FILTER: + +DMX_SET_FILTER +============== + +DESCRIPTION + +This ioctl call sets up a filter according to the filter and mask +parameters provided. A timeout may be defined stating number of seconds +to wait for a section to be loaded. A value of 0 means that no timeout +should be applied. Finally there is a flag field where it is possible to +state whether a section should be CRC-checked, whether the filter should +be a ”one-shot” filter, i.e. if the filtering operation should be +stopped after the first section is received, and whether the filtering +operation should be started immediately (without waiting for a +DMX_START ioctl call). If a filter was previously set-up, this filter +will be canceled, and the receive buffer will be flushed. + +SYNOPSIS + +int ioctl( int fd, int request = DMX_SET_FILTER, struct +dmx_sct_filter_params *params); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_SET_FILTER for this command. + + - .. row 3 + + - struct dmx_sct_filter_params *params + + - Pointer to structure containing filter parameters. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_SET_PES_FILTER: + +DMX_SET_PES_FILTER +================== + +DESCRIPTION + +This ioctl call sets up a PES filter according to the parameters +provided. By a PES filter is meant a filter that is based just on the +packet identifier (PID), i.e. no PES header or payload filtering +capability is supported. + +SYNOPSIS + +int ioctl( int fd, int request = DMX_SET_PES_FILTER, struct +dmx_pes_filter_params *params); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_SET_PES_FILTER for this command. + + - .. row 3 + + - struct dmx_pes_filter_params *params + + - Pointer to structure containing filter parameters. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EBUSY + + - This error code indicates that there are conflicting requests. + There are active filters filtering data from another input source. + Make sure that these filters are stopped before starting this + filter. + + + +.. _DMX_SET_BUFFER_SIZE: + +DMX_SET_BUFFER_SIZE +=================== + +DESCRIPTION + +This ioctl call is used to set the size of the circular buffer used for +filtered data. The default size is two maximum sized sections, i.e. if +this function is not called a buffer size of 2 * 4096 bytes will be +used. + +SYNOPSIS + +int ioctl( int fd, int request = DMX_SET_BUFFER_SIZE, unsigned long +size); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_SET_BUFFER_SIZE for this command. + + - .. row 3 + + - unsigned long size + + - Size of circular buffer. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_GET_EVENT: + +DMX_GET_EVENT +============= + +DESCRIPTION + +This ioctl call returns an event if available. If an event is not +available, the behavior depends on whether the device is in blocking or +non-blocking mode. In the latter case, the call fails immediately with +errno set to EWOULDBLOCK. In the former case, the call blocks until an +event becomes available. + +SYNOPSIS + +int ioctl( int fd, int request = DMX_GET_EVENT, struct dmx_event +*ev); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_GET_EVENT for this command. + + - .. row 3 + + - struct dmx_event *ev + + - Pointer to the location where the event is to be stored. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EWOULDBLOCK + + - There is no event pending, and the device is in non-blocking mode. + + + +.. _DMX_GET_STC: + +DMX_GET_STC +=========== + +DESCRIPTION + +This ioctl call returns the current value of the system time counter +(which is driven by a PES filter of type DMX_PES_PCR). Some hardware +supports more than one STC, so you must specify which one by setting the +num field of stc before the ioctl (range 0...n). The result is returned +in form of a ratio with a 64 bit numerator and a 32 bit denominator, so +the real 90kHz STC value is stc->stc / stc->base . + +SYNOPSIS + +int ioctl( int fd, int request = DMX_GET_STC, struct dmx_stc *stc); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_GET_STC for this command. + + - .. row 3 + + - struct dmx_stc *stc + + - Pointer to the location where the stc is to be stored. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - Invalid stc number. + + + +.. _DMX_GET_PES_PIDS: + +DMX_GET_PES_PIDS +================ + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = DMX_GET_PES_PIDS, __u16[5]); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_GET_PES_PIDS for this command. + + - .. row 3 + + - __u16[5] + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_GET_CAPS: + +DMX_GET_CAPS +============ + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = DMX_GET_CAPS, dmx_caps_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_GET_CAPS for this command. + + - .. row 3 + + - dmx_caps_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_SET_SOURCE: + +DMX_SET_SOURCE +============== + +DESCRIPTION + +This ioctl is undocumented. Documentation is welcome. + +SYNOPSIS + +int ioctl(fd, int request = DMX_SET_SOURCE, dmx_source_t *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_SET_SOURCE for this command. + + - .. row 3 + + - dmx_source_t * + + - Undocumented. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_ADD_PID: + +DMX_ADD_PID +=========== + +DESCRIPTION + +This ioctl call allows to add multiple PIDs to a transport stream filter +previously set up with DMX_SET_PES_FILTER and output equal to +DMX_OUT_TSDEMUX_TAP. + +SYNOPSIS + +int ioctl(fd, int request = DMX_ADD_PID, __u16 *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_ADD_PID for this command. + + - .. row 3 + + - __u16 * + + - PID number to be filtered. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _DMX_REMOVE_PID: + +DMX_REMOVE_PID +============== + +DESCRIPTION + +This ioctl call allows to remove a PID when multiple PIDs are set on a +transport stream filter, e. g. a filter previously set up with output +equal to DMX_OUT_TSDEMUX_TAP, created via either +DMX_SET_PES_FILTER or DMX_ADD_PID. + +SYNOPSIS + +int ioctl(fd, int request = DMX_REMOVE_PID, __u16 *); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals DMX_REMOVE_PID for this command. + + - .. row 3 + + - __u16 * + + - PID of the PES filter to be removed. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dmx_h.rst b/Documentation/linux_tv/media/dvb/dmx_h.rst new file mode 100644 index 000000000000..19e2691b7eab --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dmx_h.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dmx_h: + +********************* +DVB Demux Header File +********************* + + +.. toctree:: + :maxdepth: 1 + + ../../dmx.h + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dmx_types.rst b/Documentation/linux_tv/media/dvb/dmx_types.rst new file mode 100644 index 000000000000..83859366b73e --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dmx_types.rst @@ -0,0 +1,253 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dmx_types: + +**************** +Demux Data Types +**************** + + +.. _dmx-output-t: + +Output for the demux +==================== + + +.. _dmx-output: + +.. flat-table:: enum dmx_output + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`DMX-OUT-DECODER`: + + DMX_OUT_DECODER + + - Streaming directly to decoder. + + - .. row 3 + + - .. _`DMX-OUT-TAP`: + + DMX_OUT_TAP + + - Output going to a memory buffer (to be retrieved via the read + command). Delivers the stream output to the demux device on which + the ioctl is called. + + - .. row 4 + + - .. _`DMX-OUT-TS-TAP`: + + DMX_OUT_TS_TAP + + - Output multiplexed into a new TS (to be retrieved by reading from + the logical DVR device). Routes output to the logical DVR device + ``/dev/dvb/adapter?/dvr?``, which delivers a TS multiplexed from + all filters for which ``DMX_OUT_TS_TAP`` was specified. + + - .. row 5 + + - .. _`DMX-OUT-TSDEMUX-TAP`: + + DMX_OUT_TSDEMUX_TAP + + - Like :ref:`DMX_OUT_TS_TAP ` but retrieved + from the DMX device. + + + +.. _dmx-input-t: + +dmx_input_t +=========== + + +.. code-block:: c + + typedef enum + { + DMX_IN_FRONTEND, /* Input from a front-end device. */ + DMX_IN_DVR /* Input from the logical DVR device. */ + } dmx_input_t; + + +.. _dmx-pes-type-t: + +dmx_pes_type_t +============== + + +.. code-block:: c + + typedef enum + { + DMX_PES_AUDIO0, + DMX_PES_VIDEO0, + DMX_PES_TELETEXT0, + DMX_PES_SUBTITLE0, + DMX_PES_PCR0, + + DMX_PES_AUDIO1, + DMX_PES_VIDEO1, + DMX_PES_TELETEXT1, + DMX_PES_SUBTITLE1, + DMX_PES_PCR1, + + DMX_PES_AUDIO2, + DMX_PES_VIDEO2, + DMX_PES_TELETEXT2, + DMX_PES_SUBTITLE2, + DMX_PES_PCR2, + + DMX_PES_AUDIO3, + DMX_PES_VIDEO3, + DMX_PES_TELETEXT3, + DMX_PES_SUBTITLE3, + DMX_PES_PCR3, + + DMX_PES_OTHER + } dmx_pes_type_t; + + +.. _dmx-filter: + +struct dmx_filter +================= + + +.. code-block:: c + + typedef struct dmx_filter + { + __u8 filter[DMX_FILTER_SIZE]; + __u8 mask[DMX_FILTER_SIZE]; + __u8 mode[DMX_FILTER_SIZE]; + } dmx_filter_t; + + +.. _dmx-sct-filter-params: + +struct dmx_sct_filter_params +============================ + + +.. code-block:: c + + struct dmx_sct_filter_params + { + __u16 pid; + dmx_filter_t filter; + __u32 timeout; + __u32 flags; + #define DMX_CHECK_CRC 1 + #define DMX_ONESHOT 2 + #define DMX_IMMEDIATE_START 4 + #define DMX_KERNEL_CLIENT 0x8000 + }; + + +.. _dmx-pes-filter-params: + +struct dmx_pes_filter_params +============================ + + +.. code-block:: c + + struct dmx_pes_filter_params + { + __u16 pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pes_type; + __u32 flags; + }; + + +.. _dmx-event: + +struct dmx_event +================ + + +.. code-block:: c + + struct dmx_event + { + dmx_event_t event; + time_t timeStamp; + union + { + dmx_scrambling_status_t scrambling; + } u; + }; + + +.. _dmx-stc: + +struct dmx_stc +============== + + +.. code-block:: c + + struct dmx_stc { + unsigned int num; /* input : which STC? 0..N */ + unsigned int base; /* output: divisor for stc to get 90 kHz clock */ + __u64 stc; /* output: stc in 'base'*90 kHz units */ + }; + + +.. _dmx-caps: + +struct dmx_caps +=============== + + +.. code-block:: c + + typedef struct dmx_caps { + __u32 caps; + int num_decoders; + } dmx_caps_t; + + +.. _dmx-source-t: + +enum dmx_source_t +================= + + +.. code-block:: c + + typedef enum { + DMX_SOURCE_FRONT0 = 0, + DMX_SOURCE_FRONT1, + DMX_SOURCE_FRONT2, + DMX_SOURCE_FRONT3, + DMX_SOURCE_DVR0 = 16, + DMX_SOURCE_DVR1, + DMX_SOURCE_DVR2, + DMX_SOURCE_DVR3 + } dmx_source_t; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dtv-fe-stats.rst b/Documentation/linux_tv/media/dvb/dtv-fe-stats.rst new file mode 100644 index 000000000000..17b26fa050f5 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dtv-fe-stats.rst @@ -0,0 +1,28 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dtv-fe-stats: + +******************* +struct dtv_fe_stats +******************* + + +.. code-block:: c + + #define MAX_DTV_STATS 4 + + struct dtv_fe_stats { + __u8 len; + struct dtv_stats stat[MAX_DTV_STATS]; + } __packed; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dtv-properties.rst b/Documentation/linux_tv/media/dvb/dtv-properties.rst new file mode 100644 index 000000000000..b1b28342d09d --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dtv-properties.rst @@ -0,0 +1,26 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dtv-properties: + +********************* +struct dtv_properties +********************* + + +.. code-block:: c + + struct dtv_properties { + __u32 num; + struct dtv_property *props; + }; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dtv-property.rst b/Documentation/linux_tv/media/dvb/dtv-property.rst new file mode 100644 index 000000000000..4dff00eb610c --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dtv-property.rst @@ -0,0 +1,42 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dtv-property: + +******************* +struct dtv_property +******************* + + +.. code-block:: c + + /* Reserved fields should be set to 0 */ + + struct dtv_property { + __u32 cmd; + __u32 reserved[3]; + union { + __u32 data; + struct dtv_fe_stats st; + struct { + __u8 data[32]; + __u32 len; + __u32 reserved1[3]; + void *reserved2; + } buffer; + } u; + int result; + } __attribute__ ((packed)); + + /* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ + #define DTV_IOCTL_MAX_MSGS 64 + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dtv-stats.rst b/Documentation/linux_tv/media/dvb/dtv-stats.rst new file mode 100644 index 000000000000..e70e5a5283ff --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dtv-stats.rst @@ -0,0 +1,29 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dtv-stats: + +**************** +struct dtv_stats +**************** + + +.. code-block:: c + + struct dtv_stats { + __u8 scale; /* enum fecap_scale_params type */ + union { + __u64 uvalue; /* for counters and relative scales */ + __s64 svalue; /* for 1/1000 dB measures */ + }; + } __packed; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dvb-fe-read-status.rst b/Documentation/linux_tv/media/dvb/dvb-fe-read-status.rst new file mode 100644 index 000000000000..12d8749e9e05 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dvb-fe-read-status.rst @@ -0,0 +1,31 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb-fe-read-status: + +*************************************** +Querying frontend status and statistics +*************************************** + +Once :ref:`FE_SET_PROPERTY ` is called, the +frontend will run a kernel thread that will periodically check for the +tuner lock status and provide statistics about the quality of the +signal. + +The information about the frontend tuner locking status can be queried +using :ref:`FE_READ_STATUS `. + +Signal statistics are provided via +:ref:`FE_GET_PROPERTY `. Please note that several +statistics require the demodulator to be fully locked (e. g. with +FE_HAS_LOCK bit set). See +:ref:`Frontend statistics indicators ` for +more details. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dvb-frontend-event.rst b/Documentation/linux_tv/media/dvb/dvb-frontend-event.rst new file mode 100644 index 000000000000..82965e4d7450 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dvb-frontend-event.rst @@ -0,0 +1,26 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb-frontend-event: + +*************** +frontend events +*************** + + +.. code-block:: c + + struct dvb_frontend_event { + fe_status_t status; + struct dvb_frontend_parameters parameters; + }; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dvb-frontend-parameters.rst b/Documentation/linux_tv/media/dvb/dvb-frontend-parameters.rst new file mode 100644 index 000000000000..0a1766f68917 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dvb-frontend-parameters.rst @@ -0,0 +1,130 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb-frontend-parameters: + +******************* +frontend parameters +******************* + +The kind of parameters passed to the frontend device for tuning depend +on the kind of hardware you are using. + +The struct ``dvb_frontend_parameters`` uses an union with specific +per-system parameters. However, as newer delivery systems required more +data, the structure size weren't enough to fit, and just extending its +size would break the existing applications. So, those parameters were +replaced by the usage of +:ref:`FE_GET_PROPERTY/FE_SET_PROPERTY ` +ioctl's. The new API is flexible enough to add new parameters to +existing delivery systems, and to add newer delivery systems. + +So, newer applications should use +:ref:`FE_GET_PROPERTY/FE_SET_PROPERTY ` +instead, in order to be able to support the newer System Delivery like +DVB-S2, DVB-T2, DVB-C2, ISDB, etc. + +All kinds of parameters are combined as an union in the +FrontendParameters structure: + + +.. code-block:: c + + struct dvb_frontend_parameters { + uint32_t frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t inversion; + union { + struct dvb_qpsk_parameters qpsk; + struct dvb_qam_parameters qam; + struct dvb_ofdm_parameters ofdm; + struct dvb_vsb_parameters vsb; + } u; + }; + +In the case of QPSK frontends the ``frequency`` field specifies the +intermediate frequency, i.e. the offset which is effectively added to +the local oscillator frequency (LOF) of the LNB. The intermediate +frequency has to be specified in units of kHz. For QAM and OFDM +frontends the ``frequency`` specifies the absolute frequency and is +given in Hz. + + +.. _dvb-qpsk-parameters: + +QPSK parameters +=============== + +For satellite QPSK frontends you have to use the ``dvb_qpsk_parameters`` +structure: + + +.. code-block:: c + + struct dvb_qpsk_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + }; + + +.. _dvb-qam-parameters: + +QAM parameters +============== + +for cable QAM frontend you use the ``dvb_qam_parameters`` structure: + + +.. code-block:: c + + struct dvb_qam_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + fe_modulation_t modulation; /* modulation type (see above) */ + }; + + +.. _dvb-vsb-parameters: + +VSB parameters +============== + +ATSC frontends are supported by the ``dvb_vsb_parameters`` structure: + + +.. code-block:: c + + struct dvb_vsb_parameters { + fe_modulation_t modulation; /* modulation type (see above) */ + }; + + +.. _dvb-ofdm-parameters: + +OFDM parameters +=============== + +DVB-T frontends are supported by the ``dvb_ofdm_parameters`` structure: + + +.. code-block:: c + + struct dvb_ofdm_parameters { + fe_bandwidth_t bandwidth; + fe_code_rate_t code_rate_HP; /* high priority stream code rate */ + fe_code_rate_t code_rate_LP; /* low priority stream code rate */ + fe_modulation_t constellation; /* modulation type (see above) */ + fe_transmit_mode_t transmission_mode; + fe_guard_interval_t guard_interval; + fe_hierarchy_t hierarchy_information; + }; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dvbapi.rst b/Documentation/linux_tv/media/dvb/dvbapi.rst new file mode 100644 index 000000000000..5e513ac86052 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dvbapi.rst @@ -0,0 +1,95 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvbapi: + +############# +LINUX DVB API +############# + +**Version 5.10** + +.. toctree:: + :maxdepth: 1 + + intro + frontend + demux + ca + net + legacy_dvb_apis + examples + audio_h + ca_h + dmx_h + frontend_h + net_h + video_h + + +********************** +Revision and Copyright +********************** + + +:author: Metzler Ralph (*J. K.*) +:address: rjkm@metzlerbros.de + +:author: Metzler Marcus (*O. C.*) +:address: rjkm@metzlerbros.de + +:author: Chehab Mauro (*Carvalho*) +:address: m.chehab@samsung.com +:contrib: Ported document to Docbook XML. + +**Copyright** 2002, 2003 : Convergence GmbH + +**Copyright** 2009-2015 : Mauro Carvalho Chehab + +:revision: 2.1.0 / 2015-05-29 (*mcc*) + +DocBook improvements and cleanups, in order to document the system calls +on a more standard way and provide more description about the current +DVB API. + + +:revision: 2.0.4 / 2011-05-06 (*mcc*) + +Add more information about DVB APIv5, better describing the frontend +GET/SET props ioctl's. + + +:revision: 2.0.3 / 2010-07-03 (*mcc*) + +Add some frontend capabilities flags, present on kernel, but missing at +the specs. + + +:revision: 2.0.2 / 2009-10-25 (*mcc*) + +documents FE_SET_FRONTEND_TUNE_MODE and +FE_DISHETWORK_SEND_LEGACY_CMD ioctls. + + +:revision: 2.0.1 / 2009-09-16 (*mcc*) + +Added ISDB-T test originally written by Patrick Boettcher + + +:revision: 2.0.0 / 2009-09-06 (*mcc*) + +Conversion from LaTex to DocBook XML. The contents is the same as the +original LaTex version. + + +:revision: 1.0.0 / 2003-07-24 (*rjkm*) + +Initial revision on LaTEX. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dvbproperty-006.rst b/Documentation/linux_tv/media/dvb/dvbproperty-006.rst new file mode 100644 index 000000000000..4b89d607358c --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dvbproperty-006.rst @@ -0,0 +1,21 @@ +.. -*- coding: utf-8; mode: rst -*- + +************** +Property types +************** + +On :ref:`FE_GET_PROPERTY and FE_SET_PROPERTY `, +the actual action is determined by the dtv_property cmd/data pairs. +With one single ioctl, is possible to get/set up to 64 properties. The +actual meaning of each property is described on the next sections. + +The available frontend property types are shown on the next section. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/dvbproperty.rst b/Documentation/linux_tv/media/dvb/dvbproperty.rst new file mode 100644 index 000000000000..a68b17808bc2 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/dvbproperty.rst @@ -0,0 +1,122 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend-properties: + +DVB Frontend properties +======================= + +Tuning into a Digital TV physical channel and starting decoding it +requires changing a set of parameters, in order to control the tuner, +the demodulator, the Linear Low-noise Amplifier (LNA) and to set the +antenna subsystem via Satellite Equipment Control (SEC), on satellite +systems. The actual parameters are specific to each particular digital +TV standards, and may change as the digital TV specs evolves. + +In the past, the strategy used was to have a union with the parameters +needed to tune for DVB-S, DVB-C, DVB-T and ATSC delivery systems grouped +there. The problem is that, as the second generation standards appeared, +those structs were not big enough to contain the additional parameters. +Also, the union didn't have any space left to be expanded without +breaking userspace. So, the decision was to deprecate the legacy +union/struct based approach, in favor of a properties set approach. + +NOTE: on Linux DVB API version 3, setting a frontend were done via +:ref:`struct dvb_frontend_parameters `. +This got replaced on version 5 (also called "S2API", as this API were +added originally_enabled to provide support for DVB-S2), because the +old API has a very limited support to new standards and new hardware. +This section describes the new and recommended way to set the frontend, +with suppports all digital TV delivery systems. + +Example: with the properties based approach, in order to set the tuner +to a DVB-C channel at 651 kHz, modulated with 256-QAM, FEC 3/4 and +symbol rate of 5.217 Mbauds, those properties should be sent to +:ref:`FE_SET_PROPERTY ` ioctl: + +- :ref:`DTV_DELIVERY_SYSTEM ` = + SYS_DVBC_ANNEX_A + +- :ref:`DTV_FREQUENCY ` = 651000000 + +- :ref:`DTV_MODULATION ` = QAM_256 + +- :ref:`DTV_INVERSION ` = INVERSION_AUTO + +- :ref:`DTV_SYMBOL_RATE ` = 5217000 + +- :ref:`DTV_INNER_FEC ` = FEC_3_4 + +- :ref:`DTV_TUNE ` + +The code that would do the above is: + + +.. code-block:: c + + #include + #include + #include + #include + + static struct dtv_property props[] = { + { .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBC_ANNEX_A }, + { .cmd = DTV_FREQUENCY, .u.data = 651000000 }, + { .cmd = DTV_MODULATION, .u.data = QAM_256 }, + { .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO }, + { .cmd = DTV_SYMBOL_RATE, .u.data = 5217000 }, + { .cmd = DTV_INNER_FEC, .u.data = FEC_3_4 }, + { .cmd = DTV_TUNE } + }; + + static struct dtv_properties dtv_prop = { + .num = 6, .props = props + }; + + int main(void) + { + int fd = open("/dev/dvb/adapter0/frontend0", O_RDWR); + + if (!fd) { + perror ("open"); + return -1; + } + if (ioctl(fd, FE_SET_PROPERTY, &dtv_prop) == -1) { + perror("ioctl"); + return -1; + } + printf("Frontend set\\n"); + return 0; + } + +NOTE: While it is possible to directly call the Kernel code like the +above example, it is strongly recommended to use +`libdvbv5 `__, as it +provides abstraction to work with the supported digital TV standards and +provides methods for usual operations like program scanning and to +read/write channel descriptor files. + + +.. toctree:: + :maxdepth: 1 + + dtv-stats + dtv-fe-stats + dtv-property + dtv-properties + dvbproperty-006 + fe_property_parameters + frontend-stat-properties + frontend-property-terrestrial-systems + frontend-property-cable-systems + frontend-property-satellite-systems + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/examples.rst b/Documentation/linux_tv/media/dvb/examples.rst new file mode 100644 index 000000000000..b3a94dedcd39 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/examples.rst @@ -0,0 +1,391 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_examples: + +******** +Examples +******** + +In this section we would like to present some examples for using the DVB +API. + +NOTE: This section is out of date, and the code below won't even +compile. Please refer to the +`libdvbv5 `__ for +updated/recommended examples. + + +.. _tuning: + +Tuning +====== + +We will start with a generic tuning subroutine that uses the frontend +and SEC, as well as the demux devices. The example is given for QPSK +tuners, but can easily be adjusted for QAM. + + +.. code-block:: c + + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + + #define DMX "/dev/dvb/adapter0/demux1" + #define FRONT "/dev/dvb/adapter0/frontend1" + #define SEC "/dev/dvb/adapter0/sec1" + + /* routine for checking if we have a signal and other status information*/ + int FEReadStatus(int fd, fe_status_t *stat) + { + int ans; + + if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ + perror("FE READ STATUS: "); + return -1; + } + + if (*stat & FE_HAS_POWER) + printf("FE HAS POWER\\n"); + + if (*stat & FE_HAS_SIGNAL) + printf("FE HAS SIGNAL\\n"); + + if (*stat & FE_SPECTRUM_INV) + printf("SPEKTRUM INV\\n"); + + return 0; + } + + + /* tune qpsk */ + /* freq: frequency of transponder */ + /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ + /* diseqc: DiSEqC address of the used LNB */ + /* pol: Polarisation */ + /* srate: Symbol Rate */ + /* fec. FEC */ + /* lnb_lof1: local frequency of lower LNB band */ + /* lnb_lof2: local frequency of upper LNB band */ + /* lnb_slof: switch frequency of LNB */ + + int set_qpsk_channel(int freq, int vpid, int apid, int tpid, + int diseqc, int pol, int srate, int fec, int lnb_lof1, + int lnb_lof2, int lnb_slof) + { + struct secCommand scmd; + struct secCmdSequence scmds; + struct dmx_pes_filter_params pesFilterParams; + FrontendParameters frp; + struct pollfd pfd[1]; + FrontendEvent event; + int demux1, demux2, demux3, front; + + frequency = (uint32_t) freq; + symbolrate = (uint32_t) srate; + + if((front = open(FRONT,O_RDWR)) < 0){ + perror("FRONTEND DEVICE: "); + return -1; + } + + if((sec = open(SEC,O_RDWR)) < 0){ + perror("SEC DEVICE: "); + return -1; + } + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux3 < 0){ + if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (freq < lnb_slof) { + frp.Frequency = (freq - lnb_lof1); + scmds.continuousTone = SEC_TONE_OFF; + } else { + frp.Frequency = (freq - lnb_lof2); + scmds.continuousTone = SEC_TONE_ON; + } + frp.Inversion = INVERSION_AUTO; + if (pol) scmds.voltage = SEC_VOLTAGE_18; + else scmds.voltage = SEC_VOLTAGE_13; + + scmd.type=0; + scmd.u.diseqc.addr=0x10; + scmd.u.diseqc.cmd=0x38; + scmd.u.diseqc.numParams=1; + scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | + (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | + (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); + + scmds.miniCommand=SEC_MINI_NONE; + scmds.numCommands=1; + scmds.commands=&scmd; + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + frp.u.qpsk.SymbolRate = srate; + frp.u.qpsk.FEC_inner = fec; + + if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ + perror("QPSK TUNE: "); + return -1; + } + + pfd[0].fd = front; + pfd[0].events = POLLIN; + + if (poll(pfd,1,3000)){ + if (pfd[0].revents & POLLIN){ + printf("Getting QPSK event\\n"); + if ( ioctl(front, FE_GET_EVENT, &event) + + == -EOVERFLOW){ + perror("qpsk get event"); + return -1; + } + printf("Received "); + switch(event.type){ + case FE_UNEXPECTED_EV: + printf("unexpected event\\n"); + return -1; + case FE_FAILURE_EV: + printf("failure event\\n"); + return -1; + + case FE_COMPLETION_EV: + printf("completion event\\n"); + } + } + } + + + pesFilterParams.pid = vpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pes_type = DMX_PES_VIDEO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_vpid"); + return -1; + } + + pesFilterParams.pid = apid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pes_type = DMX_PES_AUDIO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_apid"); + return -1; + } + + pesFilterParams.pid = tpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pes_type = DMX_PES_TELETEXT; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_tpid"); + return -1; + } + + return has_signal(fds); + } + +The program assumes that you are using a universal LNB and a standard +DiSEqC switch with up to 4 addresses. Of course, you could build in some +more checking if tuning was successful and maybe try to repeat the +tuning process. Depending on the external hardware, i.e. LNB and DiSEqC +switch, and weather conditions this may be necessary. + + +.. _the_dvr_device: + +The DVR device +============== + +The following program code shows how to use the DVR device for +recording. + + +.. code-block:: c + + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #define DVR "/dev/dvb/adapter0/dvr1" + #define AUDIO "/dev/dvb/adapter0/audio1" + #define VIDEO "/dev/dvb/adapter0/video1" + + #define BUFFY (188*20) + #define MAX_LENGTH (1024*1024*5) /* record 5MB */ + + + /* switch the demuxes to recording, assuming the transponder is tuned */ + + /* demux1, demux2: file descriptor of video and audio filters */ + /* vpid, apid: PIDs of video and audio channels */ + + int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) + { + struct dmx_pes_filter_params pesFilterParams; + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + pesFilterParams.pid = vpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pes_type = DMX_PES_VIDEO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("DEMUX DEVICE"); + return -1; + } + pesFilterParams.pid = apid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pes_type = DMX_PES_AUDIO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("DEMUX DEVICE"); + return -1; + } + return 0; + } + + /* start recording MAX_LENGTH , assuming the transponder is tuned */ + + /* demux1, demux2: file descriptor of video and audio filters */ + /* vpid, apid: PIDs of video and audio channels */ + int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid) + { + int i; + int len; + int written; + uint8_t buf[BUFFY]; + uint64_t length; + struct pollfd pfd[1]; + int dvr, dvr_out; + + /* open dvr device */ + if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ + perror("DVR DEVICE"); + return -1; + } + + /* switch video and audio demuxes to dvr */ + printf ("Switching dvr on\\n"); + i = switch_to_record(demux1, demux2, vpid, apid); + printf("finished: "); + + printf("Recording %2.0f MB of test file in TS format\\n", + MAX_LENGTH/(1024.0*1024.0)); + length = 0; + + /* open output file */ + if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT + |O_TRUNC, S_IRUSR|S_IWUSR + |S_IRGRP|S_IWGRP|S_IROTH| + S_IWOTH)) < 0){ + perror("Can't open file for dvr test"); + return -1; + } + + pfd[0].fd = dvr; + pfd[0].events = POLLIN; + + /* poll for dvr data and write to file */ + while (length < MAX_LENGTH ) { + if (poll(pfd,1,1)){ + if (pfd[0].revents & POLLIN){ + len = read(dvr, buf, BUFFY); + if (len < 0){ + perror("recording"); + return -1; + } + if (len > 0){ + written = 0; + while (written < len) + written += + write (dvr_out, + buf, len); + length += len; + printf("written %2.0f MB\\r", + length/1024./1024.); + } + } + } + } + return 0; + } + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-bandwidth-t.rst b/Documentation/linux_tv/media/dvb/fe-bandwidth-t.rst new file mode 100644 index 000000000000..c6e56aba012a --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-bandwidth-t.rst @@ -0,0 +1,88 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _fe-bandwidth-t: + +****************** +Frontend bandwidth +****************** + + +.. _fe-bandwidth: + +.. flat-table:: enum fe_bandwidth + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`BANDWIDTH-AUTO`: + + ``BANDWIDTH_AUTO`` + + - Autodetect bandwidth (if supported) + + - .. row 3 + + - .. _`BANDWIDTH-1-712-MHZ`: + + ``BANDWIDTH_1_712_MHZ`` + + - 1.712 MHz + + - .. row 4 + + - .. _`BANDWIDTH-5-MHZ`: + + ``BANDWIDTH_5_MHZ`` + + - 5 MHz + + - .. row 5 + + - .. _`BANDWIDTH-6-MHZ`: + + ``BANDWIDTH_6_MHZ`` + + - 6 MHz + + - .. row 6 + + - .. _`BANDWIDTH-7-MHZ`: + + ``BANDWIDTH_7_MHZ`` + + - 7 MHz + + - .. row 7 + + - .. _`BANDWIDTH-8-MHZ`: + + ``BANDWIDTH_8_MHZ`` + + - 8 MHz + + - .. row 8 + + - .. _`BANDWIDTH-10-MHZ`: + + ``BANDWIDTH_10_MHZ`` + + - 10 MHz + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-diseqc-recv-slave-reply.rst b/Documentation/linux_tv/media/dvb/fe-diseqc-recv-slave-reply.rst new file mode 100644 index 000000000000..309930f9b3cd --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-diseqc-recv-slave-reply.rst @@ -0,0 +1,88 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_DISEQC_RECV_SLAVE_REPLY: + +******************************** +ioctl FE_DISEQC_RECV_SLAVE_REPLY +******************************** + +*man FE_DISEQC_RECV_SLAVE_REPLY(2)* + +Receives reply from a DiSEqC 2.0 command + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, struct dvb_diseqc_slave_reply *argp ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_DISEQC_RECV_SLAVE_REPLY + +``argp`` + pointer to struct + :ref:`dvb_diseqc_slave_reply ` + + +Description +=========== + +Receives reply from a DiSEqC 2.0 command. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _dvb-diseqc-slave-reply: + +.. flat-table:: struct dvb_diseqc_slave_reply + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + + - .. row 1 + + - uint8_t + + - msg[4] + + - DiSEqC message (framing, data[3]) + + - .. row 2 + + - uint8_t + + - msg_len + + - Length of the DiSEqC message. Valid values are 0 to 4, where 0 + means no msg + + - .. row 3 + + - int + + - timeout + + - Return from ioctl after timeout ms with errorcode when no message + was received + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-diseqc-reset-overload.rst b/Documentation/linux_tv/media/dvb/fe-diseqc-reset-overload.rst new file mode 100644 index 000000000000..dc7ae1a02725 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-diseqc-reset-overload.rst @@ -0,0 +1,51 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_DISEQC_RESET_OVERLOAD: + +****************************** +ioctl FE_DISEQC_RESET_OVERLOAD +****************************** + +*man FE_DISEQC_RESET_OVERLOAD(2)* + +Restores the power to the antenna subsystem, if it was powered off due +to power overload. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, NULL ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_DISEQC_RESET_OVERLOAD + + +Description +=========== + +If the bus has been automatically powered off due to power overload, +this ioctl call restores the power to the bus. The call requires +read/write access to the device. This call has no effect if the device +is manually powered off. Not all DVB adapters support this ioctl. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-diseqc-send-burst.rst b/Documentation/linux_tv/media/dvb/fe-diseqc-send-burst.rst new file mode 100644 index 000000000000..34c787903eb1 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-diseqc-send-burst.rst @@ -0,0 +1,93 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_DISEQC_SEND_BURST: + +************************** +ioctl FE_DISEQC_SEND_BURST +************************** + +*man FE_DISEQC_SEND_BURST(2)* + +Sends a 22KHz tone burst for 2x1 mini DiSEqC satellite selection. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, enum fe_sec_mini_cmd *tone ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_DISEQC_SEND_BURST + +``tone`` + pointer to enum :ref:`fe_sec_mini_cmd ` + + +Description +=========== + +This ioctl is used to set the generation of a 22kHz tone burst for mini +DiSEqC satellite selection for 2x1 switches. This call requires +read/write permissions. + +It provides support for what's specified at +`Digital Satellite Equipment Control (DiSEqC) - Simple "ToneBurst" Detection Circuit specification. `__ + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _fe-sec-mini-cmd-t: + +enum fe_sec_mini_cmd +==================== + + +.. _fe-sec-mini-cmd: + +.. flat-table:: enum fe_sec_mini_cmd + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`SEC-MINI-A`: + + ``SEC_MINI_A`` + + - Sends a mini-DiSEqC 22kHz '0' Tone Burst to select satellite-A + + - .. row 3 + + - .. _`SEC-MINI-B`: + + ``SEC_MINI_B`` + + - Sends a mini-DiSEqC 22kHz '1' Data Burst to select satellite-B + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-diseqc-send-master-cmd.rst b/Documentation/linux_tv/media/dvb/fe-diseqc-send-master-cmd.rst new file mode 100644 index 000000000000..974a45f632a6 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-diseqc-send-master-cmd.rst @@ -0,0 +1,78 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_DISEQC_SEND_MASTER_CMD: + +******************************* +ioctl FE_DISEQC_SEND_MASTER_CMD +******************************* + +*man FE_DISEQC_SEND_MASTER_CMD(2)* + +Sends a DiSEqC command + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, struct dvb_diseqc_master_cmd *argp ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_DISEQC_SEND_MASTER_CMD + +``argp`` + pointer to struct + :ref:`dvb_diseqc_master_cmd ` + + +Description +=========== + +Sends a DiSEqC command to the antenna subsystem. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _dvb-diseqc-master-cmd: + +.. flat-table:: struct dvb_diseqc_master_cmd + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + + - .. row 1 + + - uint8_t + + - msg[6] + + - DiSEqC message (framing, address, command, data[3]) + + - .. row 2 + + - uint8_t + + - msg_len + + - Length of the DiSEqC message. Valid values are 3 to 6 + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-enable-high-lnb-voltage.rst b/Documentation/linux_tv/media/dvb/fe-enable-high-lnb-voltage.rst new file mode 100644 index 000000000000..207c65a44120 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-enable-high-lnb-voltage.rst @@ -0,0 +1,58 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_ENABLE_HIGH_LNB_VOLTAGE: + +******************************** +ioctl FE_ENABLE_HIGH_LNB_VOLTAGE +******************************** + +*man FE_ENABLE_HIGH_LNB_VOLTAGE(2)* + +Select output DC level between normal LNBf voltages or higher LNBf +voltages. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, unsigned int high ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_ENABLE_HIGH_LNB_VOLTAGE + +``high`` + Valid flags: + + - 0 - normal 13V and 18V. + + - >0 - enables slightly higher voltages instead of 13/18V, in order + to compensate for long antenna cables. + + +Description +=========== + +Select output DC level between normal LNBf voltages or higher LNBf +voltages between 0 (normal) or a value grater than 0 for higher +voltages. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-get-info.rst b/Documentation/linux_tv/media/dvb/fe-get-info.rst new file mode 100644 index 000000000000..5ac74c232b12 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-get-info.rst @@ -0,0 +1,434 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_GET_INFO: + +***************** +ioctl FE_GET_INFO +***************** + +*man FE_GET_INFO(2)* + +Query DVB frontend capabilities and returns information about the +front-end. This call only requires read-only access to the device + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, struct dvb_frontend_info *argp ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_GET_INFO + +``argp`` + pointer to struct struct + :ref:`dvb_frontend_info ` + + +Description +=========== + +All DVB frontend devices support the ``FE_GET_INFO`` ioctl. It is used +to identify kernel devices compatible with this specification and to +obtain information about driver and hardware capabilities. The ioctl +takes a pointer to dvb_frontend_info which is filled by the driver. +When the driver is not compatible with this specification the ioctl +returns an error. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _dvb-frontend-info: + +.. flat-table:: struct dvb_frontend_info + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + + - .. row 1 + + - char + + - name[128] + + - Name of the frontend + + - .. row 2 + + - fe_type_t + + - type + + - **DEPRECATED**. DVBv3 type. Should not be used on modern programs, + as a frontend may have more than one type. So, the DVBv5 API + should be used instead to enumerate and select the frontend type. + + - .. row 3 + + - uint32_t + + - frequency_min + + - Minimal frequency supported by the frontend + + - .. row 4 + + - uint32_t + + - frequency_max + + - Maximal frequency supported by the frontend + + - .. row 5 + + - uint32_t + + - frequency_stepsize + + - Frequency step - all frequencies are multiple of this value + + - .. row 6 + + - uint32_t + + - frequency_tolerance + + - Tolerance of the frequency + + - .. row 7 + + - uint32_t + + - symbol_rate_min + + - Minimal symbol rate (for Cable/Satellite systems), in bauds + + - .. row 8 + + - uint32_t + + - symbol_rate_max + + - Maximal symbol rate (for Cable/Satellite systems), in bauds + + - .. row 9 + + - uint32_t + + - symbol_rate_tolerance + + - Maximal symbol rate tolerance, in ppm + + - .. row 10 + + - uint32_t + + - notifier_delay + + - **DEPRECATED**. Not used by any driver. + + - .. row 11 + + - enum :ref:`fe_caps ` + + - caps + + - Capabilities supported by the frontend + + +NOTE: The frequencies are specified in Hz for Terrestrial and Cable +systems. They're specified in kHz for Satellite systems + + +.. _fe-caps-t: + +frontend capabilities +===================== + +Capabilities describe what a frontend can do. Some capabilities are +supported only on some specific frontend types. + + +.. _fe-caps: + +.. flat-table:: enum fe_caps + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`FE-IS-STUPID`: + + ``FE_IS_STUPID`` + + - There's something wrong at the frontend, and it can't report its + capabilities + + - .. row 3 + + - .. _`FE-CAN-INVERSION-AUTO`: + + ``FE_CAN_INVERSION_AUTO`` + + - The frontend is capable of auto-detecting inversion + + - .. row 4 + + - .. _`FE-CAN-FEC-1-2`: + + ``FE_CAN_FEC_1_2`` + + - The frontend supports FEC 1/2 + + - .. row 5 + + - .. _`FE-CAN-FEC-2-3`: + + ``FE_CAN_FEC_2_3`` + + - The frontend supports FEC 2/3 + + - .. row 6 + + - .. _`FE-CAN-FEC-3-4`: + + ``FE_CAN_FEC_3_4`` + + - The frontend supports FEC 3/4 + + - .. row 7 + + - .. _`FE-CAN-FEC-4-5`: + + ``FE_CAN_FEC_4_5`` + + - The frontend supports FEC 4/5 + + - .. row 8 + + - .. _`FE-CAN-FEC-5-6`: + + ``FE_CAN_FEC_5_6`` + + - The frontend supports FEC 5/6 + + - .. row 9 + + - .. _`FE-CAN-FEC-6-7`: + + ``FE_CAN_FEC_6_7`` + + - The frontend supports FEC 6/7 + + - .. row 10 + + - .. _`FE-CAN-FEC-7-8`: + + ``FE_CAN_FEC_7_8`` + + - The frontend supports FEC 7/8 + + - .. row 11 + + - .. _`FE-CAN-FEC-8-9`: + + ``FE_CAN_FEC_8_9`` + + - The frontend supports FEC 8/9 + + - .. row 12 + + - .. _`FE-CAN-FEC-AUTO`: + + ``FE_CAN_FEC_AUTO`` + + - The frontend can autodetect FEC. + + - .. row 13 + + - .. _`FE-CAN-QPSK`: + + ``FE_CAN_QPSK`` + + - The frontend supports QPSK modulation + + - .. row 14 + + - .. _`FE-CAN-QAM-16`: + + ``FE_CAN_QAM_16`` + + - The frontend supports 16-QAM modulation + + - .. row 15 + + - .. _`FE-CAN-QAM-32`: + + ``FE_CAN_QAM_32`` + + - The frontend supports 32-QAM modulation + + - .. row 16 + + - .. _`FE-CAN-QAM-64`: + + ``FE_CAN_QAM_64`` + + - The frontend supports 64-QAM modulation + + - .. row 17 + + - .. _`FE-CAN-QAM-128`: + + ``FE_CAN_QAM_128`` + + - The frontend supports 128-QAM modulation + + - .. row 18 + + - .. _`FE-CAN-QAM-256`: + + ``FE_CAN_QAM_256`` + + - The frontend supports 256-QAM modulation + + - .. row 19 + + - .. _`FE-CAN-QAM-AUTO`: + + ``FE_CAN_QAM_AUTO`` + + - The frontend can autodetect modulation + + - .. row 20 + + - .. _`FE-CAN-TRANSMISSION-MODE-AUTO`: + + ``FE_CAN_TRANSMISSION_MODE_AUTO`` + + - The frontend can autodetect the transmission mode + + - .. row 21 + + - .. _`FE-CAN-BANDWIDTH-AUTO`: + + ``FE_CAN_BANDWIDTH_AUTO`` + + - The frontend can autodetect the bandwidth + + - .. row 22 + + - .. _`FE-CAN-GUARD-INTERVAL-AUTO`: + + ``FE_CAN_GUARD_INTERVAL_AUTO`` + + - The frontend can autodetect the guard interval + + - .. row 23 + + - .. _`FE-CAN-HIERARCHY-AUTO`: + + ``FE_CAN_HIERARCHY_AUTO`` + + - The frontend can autodetect hierarch + + - .. row 24 + + - .. _`FE-CAN-8VSB`: + + ``FE_CAN_8VSB`` + + - The frontend supports 8-VSB modulation + + - .. row 25 + + - .. _`FE-CAN-16VSB`: + + ``FE_CAN_16VSB`` + + - The frontend supports 16-VSB modulation + + - .. row 26 + + - .. _`FE-HAS-EXTENDED-CAPS`: + + ``FE_HAS_EXTENDED_CAPS`` + + - Currently, unused + + - .. row 27 + + - .. _`FE-CAN-MULTISTREAM`: + + ``FE_CAN_MULTISTREAM`` + + - The frontend supports multistream filtering + + - .. row 28 + + - .. _`FE-CAN-TURBO-FEC`: + + ``FE_CAN_TURBO_FEC`` + + - The frontend supports turbo FEC modulation + + - .. row 29 + + - .. _`FE-CAN-2G-MODULATION`: + + ``FE_CAN_2G_MODULATION`` + + - The frontend supports "2nd generation modulation" (DVB-S2/T2)> + + - .. row 30 + + - .. _`FE-NEEDS-BENDING`: + + ``FE_NEEDS_BENDING`` + + - Not supported anymore, don't use it + + - .. row 31 + + - .. _`FE-CAN-RECOVER`: + + ``FE_CAN_RECOVER`` + + - The frontend can recover from a cable unplug automatically + + - .. row 32 + + - .. _`FE-CAN-MUTE-TS`: + + ``FE_CAN_MUTE_TS`` + + - The frontend can stop spurious TS data output + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-get-property.rst b/Documentation/linux_tv/media/dvb/fe-get-property.rst new file mode 100644 index 000000000000..8a6c5de041e8 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-get-property.rst @@ -0,0 +1,75 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_GET_PROPERTY: + +************************************** +ioctl FE_SET_PROPERTY, FE_GET_PROPERTY +************************************** + +*man FE_SET_PROPERTY(2)* + +FE_GET_PROPERTY +FE_SET_PROPERTY sets one or more frontend properties. +FE_GET_PROPERTY returns one or more frontend properties. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, struct dtv_properties *argp ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_PROPERTY, FE_GET_PROPERTY + +``argp`` + pointer to struct :ref:`dtv_properties ` + + +Description +=========== + +All DVB frontend devices support the ``FE_SET_PROPERTY`` and +``FE_GET_PROPERTY`` ioctls. The supported properties and statistics +depends on the delivery system and on the device: + +- ``FE_SET_PROPERTY:`` + + - This ioctl is used to set one or more frontend properties. + + - This is the basic command to request the frontend to tune into + some frequency and to start decoding the digital TV signal. + + - This call requires read/write access to the device. + + - At return, the values are updated to reflect the actual parameters + used. + +- ``FE_GET_PROPERTY:`` + + - This ioctl is used to get properties and statistics from the + frontend. + + - No properties are changed, and statistics aren't reset. + + - This call only requires read-only access to the device. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-read-status.rst b/Documentation/linux_tv/media/dvb/fe-read-status.rst new file mode 100644 index 000000000000..41396a8f1c3d --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-read-status.rst @@ -0,0 +1,143 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_READ_STATUS: + +******************** +ioctl FE_READ_STATUS +******************** + +*man FE_READ_STATUS(2)* + +Returns status information about the front-end. This call only requires +read-only access to the device + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, unsigned int *status ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_READ_STATUS + +``status`` + pointer to a bitmask integer filled with the values defined by enum + :ref:`fe_status `. + + +Description +=========== + +All DVB frontend devices support the ``FE_READ_STATUS`` ioctl. It is +used to check about the locking status of the frontend after being +tuned. The ioctl takes a pointer to an integer where the status will be +written. + +NOTE: the size of status is actually sizeof(enum fe_status), with +varies according with the architecture. This needs to be fixed in the +future. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _fe-status-t: + +int fe_status +============= + +The fe_status parameter is used to indicate the current state and/or +state changes of the frontend hardware. It is produced using the enum +:ref:`fe_status ` values on a bitmask + + +.. _fe-status: + +.. flat-table:: enum fe_status + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`FE-HAS-SIGNAL`: + + ``FE_HAS_SIGNAL`` + + - The frontend has found something above the noise level + + - .. row 3 + + - .. _`FE-HAS-CARRIER`: + + ``FE_HAS_CARRIER`` + + - The frontend has found a DVB signal + + - .. row 4 + + - .. _`FE-HAS-VITERBI`: + + ``FE_HAS_VITERBI`` + + - The frontend FEC inner coding (Viterbi, LDPC or other inner code) + is stable + + - .. row 5 + + - .. _`FE-HAS-SYNC`: + + ``FE_HAS_SYNC`` + + - Synchronization bytes was found + + - .. row 6 + + - .. _`FE-HAS-LOCK`: + + ``FE_HAS_LOCK`` + + - The DVB were locked and everything is working + + - .. row 7 + + - .. _`FE-TIMEDOUT`: + + ``FE_TIMEDOUT`` + + - no lock within the last about 2 seconds + + - .. row 8 + + - .. _`FE-REINIT`: + + ``FE_REINIT`` + + - The frontend was reinitialized, application is recommended to + reset DiSEqC, tone and parameters + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-set-frontend-tune-mode.rst b/Documentation/linux_tv/media/dvb/fe-set-frontend-tune-mode.rst new file mode 100644 index 000000000000..1167d22c2382 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-set-frontend-tune-mode.rst @@ -0,0 +1,60 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_SET_FRONTEND_TUNE_MODE: + +******************************* +ioctl FE_SET_FRONTEND_TUNE_MODE +******************************* + +*man FE_SET_FRONTEND_TUNE_MODE(2)* + +Allow setting tuner mode flags to the frontend. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, unsigned int flags ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_FRONTEND_TUNE_MODE + +``flags`` + Valid flags: + + - 0 - normal tune mode + + - FE_TUNE_MODE_ONESHOT - When set, this flag will disable any + zigzagging or other "normal" tuning behaviour. Additionally, + there will be no automatic monitoring of the lock status, and + hence no frontend events will be generated. If a frontend device + is closed, this flag will be automatically turned off when the + device is reopened read-write. + + +Description +=========== + +Allow setting tuner mode flags to the frontend, between 0 (normal) or +FE_TUNE_MODE_ONESHOT mode + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-set-tone.rst b/Documentation/linux_tv/media/dvb/fe-set-tone.rst new file mode 100644 index 000000000000..f98c4b3b8760 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-set-tone.rst @@ -0,0 +1,100 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_SET_TONE: + +***************** +ioctl FE_SET_TONE +***************** + +*man FE_SET_TONE(2)* + +Sets/resets the generation of the continuous 22kHz tone. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, enum fe_sec_tone_mode *tone ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_TONE + +``tone`` + pointer to enum :ref:`fe_sec_tone_mode ` + + +Description +=========== + +This ioctl is used to set the generation of the continuous 22kHz tone. +This call requires read/write permissions. + +Usually, satellite antenna subsystems require that the digital TV device +to send a 22kHz tone in order to select between high/low band on some +dual-band LNBf. It is also used to send signals to DiSEqC equipment, but +this is done using the DiSEqC ioctls. + +NOTE: if more than one device is connected to the same antenna, setting +a tone may interfere on other devices, as they may lose the capability +of selecting the band. So, it is recommended that applications would +change to SEC_TONE_OFF when the device is not used. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _fe-sec-tone-mode-t: + +enum fe_sec_tone_mode +===================== + + +.. _fe-sec-tone-mode: + +.. flat-table:: enum fe_sec_tone_mode + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`SEC-TONE-ON`: + + ``SEC_TONE_ON`` + + - Sends a 22kHz tone burst to the antenna + + - .. row 3 + + - .. _`SEC-TONE-OFF`: + + ``SEC_TONE_OFF`` + + - Don't send a 22kHz tone to the antenna (except if the + FE_DISEQC_* ioctls are called) + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-set-voltage.rst b/Documentation/linux_tv/media/dvb/fe-set-voltage.rst new file mode 100644 index 000000000000..eb4ab28b479a --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-set-voltage.rst @@ -0,0 +1,68 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _FE_SET_VOLTAGE: + +******************** +ioctl FE_SET_VOLTAGE +******************** + +*man FE_SET_VOLTAGE(2)* + +Allow setting the DC level sent to the antenna subsystem. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, enum fe_sec_voltage *voltage ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_VOLTAGE + +``voltage`` + pointer to enum :ref:`fe_sec_voltage ` + + Valid values are described at enum + :ref:`fe_sec_voltage `. + + +Description +=========== + +This ioctl allows to set the DC voltage level sent through the antenna +cable to 13V, 18V or off. + +Usually, a satellite antenna subsystems require that the digital TV +device to send a DC voltage to feed power to the LNBf. Depending on the +LNBf type, the polarization or the intermediate frequency (IF) of the +LNBf can controlled by the voltage level. Other devices (for example, +the ones that implement DISEqC and multipoint LNBf's don't need to +control the voltage level, provided that either 13V or 18V is sent to +power up the LNBf. + +NOTE: if more than one device is connected to the same antenna, setting +a voltage level may interfere on other devices, as they may lose the +capability of setting polarization or IF. So, on those cases, setting +the voltage to SEC_VOLTAGE_OFF while the device is not is used is +recommended. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe-type-t.rst b/Documentation/linux_tv/media/dvb/fe-type-t.rst new file mode 100644 index 000000000000..49fa8090010b --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe-type-t.rst @@ -0,0 +1,100 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _fe-type-t: + +************* +Frontend type +************* + +For historical reasons, frontend types are named by the type of +modulation used in transmission. The fontend types are given by +fe_type_t type, defined as: + + +.. _fe-type: + +.. flat-table:: Frontend types + :header-rows: 1 + :stub-columns: 0 + :widths: 3 1 4 + + + - .. row 1 + + - fe_type + + - Description + + - :ref:`DTV_DELIVERY_SYSTEM ` equivalent + type + + - .. row 2 + + - .. _`FE-QPSK`: + + ``FE_QPSK`` + + - For DVB-S standard + + - ``SYS_DVBS`` + + - .. row 3 + + - .. _`FE-QAM`: + + ``FE_QAM`` + + - For DVB-C annex A standard + + - ``SYS_DVBC_ANNEX_A`` + + - .. row 4 + + - .. _`FE-OFDM`: + + ``FE_OFDM`` + + - For DVB-T standard + + - ``SYS_DVBT`` + + - .. row 5 + + - .. _`FE-ATSC`: + + ``FE_ATSC`` + + - For ATSC standard (terrestrial) or for DVB-C Annex B (cable) used + in US. + + - ``SYS_ATSC`` (terrestrial) or ``SYS_DVBC_ANNEX_B`` (cable) + + +Newer formats like DVB-S2, ISDB-T, ISDB-S and DVB-T2 are not described +at the above, as they're supported via the new +:ref:`FE_GET_PROPERTY/FE_GET_SET_PROPERTY ` +ioctl's, using the :ref:`DTV_DELIVERY_SYSTEM ` +parameter. + +In the old days, struct :ref:`dvb_frontend_info ` +used to contain ``fe_type_t`` field to indicate the delivery systems, +filled with either FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC. While this +is still filled to keep backward compatibility, the usage of this field +is deprecated, as it can report just one delivery system, but some +devices support multiple delivery systems. Please use +:ref:`DTV_ENUM_DELSYS ` instead. + +On devices that support multiple delivery systems, struct +:ref:`dvb_frontend_info `::``fe_type_t`` is +filled with the currently standard, as selected by the last call to +:ref:`FE_SET_PROPERTY ` using the +:ref:`DTV_DELIVERY_SYSTEM ` property. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/fe_property_parameters.rst b/Documentation/linux_tv/media/dvb/fe_property_parameters.rst new file mode 100644 index 000000000000..cf8514d79a20 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/fe_property_parameters.rst @@ -0,0 +1,1976 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _fe_property_parameters: + +****************************** +Digital TV property parameters +****************************** + + +.. _DTV-UNDEFINED: + +DTV_UNDEFINED +============= + +Used internally. A GET/SET operation for it won't change or return +anything. + + +.. _DTV-TUNE: + +DTV_TUNE +======== + +Interpret the cache of data, build either a traditional frontend +tunerequest so we can pass validation in the ``FE_SET_FRONTEND`` ioctl. + + +.. _DTV-CLEAR: + +DTV_CLEAR +========= + +Reset a cache of data specific to the frontend here. This does not +effect hardware. + + +.. _DTV-FREQUENCY: + +DTV_FREQUENCY +============= + +Central frequency of the channel. + +Notes: + +1)For satellite delivery systems, it is measured in kHz. For the other +ones, it is measured in Hz. + +2)For ISDB-T, the channels are usually transmitted with an offset of +143kHz. E.g. a valid frequency could be 474143 kHz. The stepping is +bound to the bandwidth of the channel which is 6MHz. + +3)As in ISDB-Tsb the channel consists of only one or three segments the +frequency step is 429kHz, 3*429 respectively. As for ISDB-T the central +frequency of the channel is expected. + + +.. _DTV-MODULATION: + +DTV_MODULATION +============== + +Specifies the frontend modulation type for delivery systems that +supports more than one modulation type. The modulation can be one of the +types defined by enum :ref:`fe_modulation `. + + +.. _fe-modulation-t: + +Modulation property +------------------- + +Most of the digital TV standards currently offers more than one possible +modulation (sometimes called as "constellation" on some standards). This +enum contains the values used by the Kernel. Please note that not all +modulations are supported by a given standard. + + +.. _fe-modulation: + +.. flat-table:: enum fe_modulation + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`QPSK`: + + ``QPSK`` + + - QPSK modulation + + - .. row 3 + + - .. _`QAM-16`: + + ``QAM_16`` + + - 16-QAM modulation + + - .. row 4 + + - .. _`QAM-32`: + + ``QAM_32`` + + - 32-QAM modulation + + - .. row 5 + + - .. _`QAM-64`: + + ``QAM_64`` + + - 64-QAM modulation + + - .. row 6 + + - .. _`QAM-128`: + + ``QAM_128`` + + - 128-QAM modulation + + - .. row 7 + + - .. _`QAM-256`: + + ``QAM_256`` + + - 256-QAM modulation + + - .. row 8 + + - .. _`QAM-AUTO`: + + ``QAM_AUTO`` + + - Autodetect QAM modulation + + - .. row 9 + + - .. _`VSB-8`: + + ``VSB_8`` + + - 8-VSB modulation + + - .. row 10 + + - .. _`VSB-16`: + + ``VSB_16`` + + - 16-VSB modulation + + - .. row 11 + + - .. _`PSK-8`: + + ``PSK_8`` + + - 8-PSK modulation + + - .. row 12 + + - .. _`APSK-16`: + + ``APSK_16`` + + - 16-APSK modulation + + - .. row 13 + + - .. _`APSK-32`: + + ``APSK_32`` + + - 32-APSK modulation + + - .. row 14 + + - .. _`DQPSK`: + + ``DQPSK`` + + - DQPSK modulation + + - .. row 15 + + - .. _`QAM-4-NR`: + + ``QAM_4_NR`` + + - 4-QAM-NR modulation + + + +.. _DTV-BANDWIDTH-HZ: + +DTV_BANDWIDTH_HZ +================ + +Bandwidth for the channel, in HZ. + +Possible values: ``1712000``, ``5000000``, ``6000000``, ``7000000``, +``8000000``, ``10000000``. + +Notes: + +1) For ISDB-T it should be always 6000000Hz (6MHz) + +2) For ISDB-Tsb it can vary depending on the number of connected +segments + +3) Bandwidth doesn't apply for DVB-C transmissions, as the bandwidth for +DVB-C depends on the symbol rate + +4) Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from +other parameters (DTV_ISDBT_SB_SEGMENT_IDX, +DTV_ISDBT_SB_SEGMENT_COUNT). + +5) DVB-T supports 6, 7 and 8MHz. + +6) In addition, DVB-T2 supports 1.172, 5 and 10MHz. + + +.. _DTV-INVERSION: + +DTV_INVERSION +============= + +Specifies if the frontend should do spectral inversion or not. + + +.. _fe-spectral-inversion-t: + +enum fe_modulation: Frontend spectral inversion +----------------------------------------------- + +This parameter indicates if spectral inversion should be presumed or +not. In the automatic setting (``INVERSION_AUTO``) the hardware will try +to figure out the correct setting by itself. If the hardware doesn't +support, the DVB core will try to lock at the carrier first with +inversion off. If it fails, it will try to enable inversion. + + +.. _fe-spectral-inversion: + +.. flat-table:: enum fe_modulation + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`INVERSION-OFF`: + + ``INVERSION_OFF`` + + - Don't do spectral band inversion. + + - .. row 3 + + - .. _`INVERSION-ON`: + + ``INVERSION_ON`` + + - Do spectral band inversion. + + - .. row 4 + + - .. _`INVERSION-AUTO`: + + ``INVERSION_AUTO`` + + - Autodetect spectral band inversion. + + + +.. _DTV-DISEQC-MASTER: + +DTV_DISEQC_MASTER +================= + +Currently not implemented. + + +.. _DTV-SYMBOL-RATE: + +DTV_SYMBOL_RATE +=============== + +Digital TV symbol rate, in bauds (symbols/second). Used on cable +standards. + + +.. _DTV-INNER-FEC: + +DTV_INNER_FEC +============= + +Used cable/satellite transmissions. The acceptable values are: + + +.. _fe-code-rate-t: + +enum fe_code_rate: type of the Forward Error Correction. +-------------------------------------------------------- + + +.. _fe-code-rate: + +.. flat-table:: enum fe_code_rate + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`FEC-NONE`: + + ``FEC_NONE`` + + - No Forward Error Correction Code + + - .. row 3 + + - .. _`FEC-AUTO`: + + ``FEC_AUTO`` + + - Autodetect Error Correction Code + + - .. row 4 + + - .. _`FEC-1-2`: + + ``FEC_1_2`` + + - Forward Error Correction Code 1/2 + + - .. row 5 + + - .. _`FEC-2-3`: + + ``FEC_2_3`` + + - Forward Error Correction Code 2/3 + + - .. row 6 + + - .. _`FEC-3-4`: + + ``FEC_3_4`` + + - Forward Error Correction Code 3/4 + + - .. row 7 + + - .. _`FEC-4-5`: + + ``FEC_4_5`` + + - Forward Error Correction Code 4/5 + + - .. row 8 + + - .. _`FEC-5-6`: + + ``FEC_5_6`` + + - Forward Error Correction Code 5/6 + + - .. row 9 + + - .. _`FEC-6-7`: + + ``FEC_6_7`` + + - Forward Error Correction Code 6/7 + + - .. row 10 + + - .. _`FEC-7-8`: + + ``FEC_7_8`` + + - Forward Error Correction Code 7/8 + + - .. row 11 + + - .. _`FEC-8-9`: + + ``FEC_8_9`` + + - Forward Error Correction Code 8/9 + + - .. row 12 + + - .. _`FEC-9-10`: + + ``FEC_9_10`` + + - Forward Error Correction Code 9/10 + + - .. row 13 + + - .. _`FEC-2-5`: + + ``FEC_2_5`` + + - Forward Error Correction Code 2/5 + + - .. row 14 + + - .. _`FEC-3-5`: + + ``FEC_3_5`` + + - Forward Error Correction Code 3/5 + + + +.. _DTV-VOLTAGE: + +DTV_VOLTAGE +=========== + +The voltage is usually used with non-DiSEqC capable LNBs to switch the +polarzation (horizontal/vertical). When using DiSEqC epuipment this +voltage has to be switched consistently to the DiSEqC commands as +described in the DiSEqC spec. + + +.. _fe-sec-voltage: + +.. flat-table:: enum fe_sec_voltage + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`SEC-VOLTAGE-13`: + + ``SEC_VOLTAGE_13`` + + - Set DC voltage level to 13V + + - .. row 3 + + - .. _`SEC-VOLTAGE-18`: + + ``SEC_VOLTAGE_18`` + + - Set DC voltage level to 18V + + - .. row 4 + + - .. _`SEC-VOLTAGE-OFF`: + + ``SEC_VOLTAGE_OFF`` + + - Don't send any voltage to the antenna + + + +.. _DTV-TONE: + +DTV_TONE +======== + +Currently not used. + + +.. _DTV-PILOT: + +DTV_PILOT +========= + +Sets DVB-S2 pilot + + +.. _fe-pilot-t: + +fe_pilot type +------------- + + +.. _fe-pilot: + +.. flat-table:: enum fe_pilot + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`PILOT-ON`: + + ``PILOT_ON`` + + - Pilot tones enabled + + - .. row 3 + + - .. _`PILOT-OFF`: + + ``PILOT_OFF`` + + - Pilot tones disabled + + - .. row 4 + + - .. _`PILOT-AUTO`: + + ``PILOT_AUTO`` + + - Autodetect pilot tones + + + +.. _DTV-ROLLOFF: + +DTV_ROLLOFF +=========== + +Sets DVB-S2 rolloff + + +.. _fe-rolloff-t: + +fe_rolloff type +--------------- + + +.. _fe-rolloff: + +.. flat-table:: enum fe_rolloff + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`ROLLOFF-35`: + + ``ROLLOFF_35`` + + - Roloff factor: α=35% + + - .. row 3 + + - .. _`ROLLOFF-20`: + + ``ROLLOFF_20`` + + - Roloff factor: α=20% + + - .. row 4 + + - .. _`ROLLOFF-25`: + + ``ROLLOFF_25`` + + - Roloff factor: α=25% + + - .. row 5 + + - .. _`ROLLOFF-AUTO`: + + ``ROLLOFF_AUTO`` + + - Auto-detect the roloff factor. + + + +.. _DTV-DISEQC-SLAVE-REPLY: + +DTV_DISEQC_SLAVE_REPLY +====================== + +Currently not implemented. + + +.. _DTV-FE-CAPABILITY-COUNT: + +DTV_FE_CAPABILITY_COUNT +======================= + +Currently not implemented. + + +.. _DTV-FE-CAPABILITY: + +DTV_FE_CAPABILITY +================= + +Currently not implemented. + + +.. _DTV-DELIVERY-SYSTEM: + +DTV_DELIVERY_SYSTEM +=================== + +Specifies the type of Delivery system + + +.. _fe-delivery-system-t: + +fe_delivery_system type +----------------------- + +Possible values: + + +.. _fe-delivery-system: + +.. flat-table:: enum fe_delivery_system + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`SYS-UNDEFINED`: + + ``SYS_UNDEFINED`` + + - Undefined standard. Generally, indicates an error + + - .. row 3 + + - .. _`SYS-DVBC-ANNEX-A`: + + ``SYS_DVBC_ANNEX_A`` + + - Cable TV: DVB-C following ITU-T J.83 Annex A spec + + - .. row 4 + + - .. _`SYS-DVBC-ANNEX-B`: + + ``SYS_DVBC_ANNEX_B`` + + - Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM) + + - .. row 5 + + - .. _`SYS-DVBC-ANNEX-C`: + + ``SYS_DVBC_ANNEX_C`` + + - Cable TV: DVB-C following ITU-T J.83 Annex C spec + + - .. row 6 + + - .. _`SYS-ISDBC`: + + ``SYS_ISDBC`` + + - Cable TV: ISDB-C (no drivers yet) + + - .. row 7 + + - .. _`SYS-DVBT`: + + ``SYS_DVBT`` + + - Terrestral TV: DVB-T + + - .. row 8 + + - .. _`SYS-DVBT2`: + + ``SYS_DVBT2`` + + - Terrestral TV: DVB-T2 + + - .. row 9 + + - .. _`SYS-ISDBT`: + + ``SYS_ISDBT`` + + - Terrestral TV: ISDB-T + + - .. row 10 + + - .. _`SYS-ATSC`: + + ``SYS_ATSC`` + + - Terrestral TV: ATSC + + - .. row 11 + + - .. _`SYS-ATSCMH`: + + ``SYS_ATSCMH`` + + - Terrestral TV (mobile): ATSC-M/H + + - .. row 12 + + - .. _`SYS-DTMB`: + + ``SYS_DTMB`` + + - Terrestrial TV: DTMB + + - .. row 13 + + - .. _`SYS-DVBS`: + + ``SYS_DVBS`` + + - Satellite TV: DVB-S + + - .. row 14 + + - .. _`SYS-DVBS2`: + + ``SYS_DVBS2`` + + - Satellite TV: DVB-S2 + + - .. row 15 + + - .. _`SYS-TURBO`: + + ``SYS_TURBO`` + + - Satellite TV: DVB-S Turbo + + - .. row 16 + + - .. _`SYS-ISDBS`: + + ``SYS_ISDBS`` + + - Satellite TV: ISDB-S + + - .. row 17 + + - .. _`SYS-DAB`: + + ``SYS_DAB`` + + - Digital audio: DAB (not fully supported) + + - .. row 18 + + - .. _`SYS-DSS`: + + ``SYS_DSS`` + + - Satellite TV:"DSS (not fully supported) + + - .. row 19 + + - .. _`SYS-CMMB`: + + ``SYS_CMMB`` + + - Terrestral TV (mobile):CMMB (not fully supported) + + - .. row 20 + + - .. _`SYS-DVBH`: + + ``SYS_DVBH`` + + - Terrestral TV (mobile): DVB-H (standard deprecated) + + + +.. _DTV-ISDBT-PARTIAL-RECEPTION: + +DTV_ISDBT_PARTIAL_RECEPTION +=========================== + +If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents +whether the channel is in partial reception mode or not. + +If '1' ``DTV_ISDBT_LAYERA_*`` values are assigned to the center segment +and ``DTV_ISDBT_LAYERA_SEGMENT_COUNT`` has to be '1'. + +If in addition ``DTV_ISDBT_SOUND_BROADCASTING`` is '1' +``DTV_ISDBT_PARTIAL_RECEPTION`` represents whether this ISDB-Tsb channel +is consisting of one segment and layer or three segments and two layers. + +Possible values: 0, 1, -1 (AUTO) + + +.. _DTV-ISDBT-SOUND-BROADCASTING: + +DTV_ISDBT_SOUND_BROADCASTING +============================ + +This field represents whether the other DTV_ISDBT_*-parameters are +referring to an ISDB-T and an ISDB-Tsb channel. (See also +``DTV_ISDBT_PARTIAL_RECEPTION``). + +Possible values: 0, 1, -1 (AUTO) + + +.. _DTV-ISDBT-SB-SUBCHANNEL-ID: + +DTV_ISDBT_SB_SUBCHANNEL_ID +========================== + +This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. + +(Note of the author: This might not be the correct description of the +``SUBCHANNEL-ID`` in all details, but it is my understanding of the +technical background needed to program a device) + +An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a +set of connected ISDB-Tsb channels. In this set of channels every +channel can be received independently. The number of connected ISDB-Tsb +segment can vary, e.g. depending on the frequency spectrum bandwidth +available. + +Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The +broadcaster has several possibilities to put those channels in the air: +Assuming a normal 13-segment ISDB-T spectrum he can align the 8 segments +from position 1-8 to 5-13 or anything in between. + +The underlying layer of segments are subchannels: each segment is +consisting of several subchannels with a predefined IDs. A sub-channel +is used to help the demodulator to synchronize on the channel. + +An ISDB-T channel is always centered over all sub-channels. As for the +example above, in ISDB-Tsb it is no longer as simple as that. + +``The DTV_ISDBT_SB_SUBCHANNEL_ID`` parameter is used to give the +sub-channel ID of the segment to be demodulated. + +Possible values: 0 .. 41, -1 (AUTO) + + +.. _DTV-ISDBT-SB-SEGMENT-IDX: + +DTV_ISDBT_SB_SEGMENT_IDX +======================== + +This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. + +``DTV_ISDBT_SB_SEGMENT_IDX`` gives the index of the segment to be +demodulated for an ISDB-Tsb channel where several of them are +transmitted in the connected manner. + +Possible values: 0 .. ``DTV_ISDBT_SB_SEGMENT_COUNT`` - 1 + +Note: This value cannot be determined by an automatic channel search. + + +.. _DTV-ISDBT-SB-SEGMENT-COUNT: + +DTV_ISDBT_SB_SEGMENT_COUNT +========================== + +This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. + +``DTV_ISDBT_SB_SEGMENT_COUNT`` gives the total count of connected +ISDB-Tsb channels. + +Possible values: 1 .. 13 + +Note: This value cannot be determined by an automatic channel search. + + +.. _isdb-hierq-layers: + +DTV-ISDBT-LAYER* parameters +=========================== + +ISDB-T channels can be coded hierarchically. As opposed to DVB-T in +ISDB-T hierarchical layers can be decoded simultaneously. For that +reason a ISDB-T demodulator has 3 Viterbi and 3 Reed-Solomon decoders. + +ISDB-T has 3 hierarchical layers which each can use a part of the +available segments. The total number of segments over all layers has to +13 in ISDB-T. + +There are 3 parameter sets, for Layers A, B and C. + + +.. _DTV-ISDBT-LAYER-ENABLED: + +DTV_ISDBT_LAYER_ENABLED +----------------------- + +Hierarchical reception in ISDB-T is achieved by enabling or disabling +layers in the decoding process. Setting all bits of +``DTV_ISDBT_LAYER_ENABLED`` to '1' forces all layers (if applicable) to +be demodulated. This is the default. + +If the channel is in the partial reception mode +(``DTV_ISDBT_PARTIAL_RECEPTION`` = 1) the central segment can be decoded +independently of the other 12 segments. In that mode layer A has to have +a ``SEGMENT_COUNT`` of 1. + +In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb according +to ``DTV_ISDBT_PARTIAL_RECEPTION``. ``SEGMENT_COUNT`` must be filled +accordingly. + +Possible values: 0x1, 0x2, 0x4 (|-able) + +``DTV_ISDBT_LAYER_ENABLED[0:0]`` - layer A + +``DTV_ISDBT_LAYER_ENABLED[1:1]`` - layer B + +``DTV_ISDBT_LAYER_ENABLED[2:2]`` - layer C + +``DTV_ISDBT_LAYER_ENABLED[31:3]`` unused + + +.. _DTV-ISDBT-LAYER-FEC: + +DTV_ISDBT_LAYER*_FEC +-------------------- + +Possible values: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``, +``FEC_5_6``, ``FEC_7_8`` + + +.. _DTV-ISDBT-LAYER-MODULATION: + +DTV_ISDBT_LAYER*_MODULATION +--------------------------- + +Possible values: ``QAM_AUTO``, QP\ ``SK, QAM_16``, ``QAM_64``, ``DQPSK`` + +Note: If layer C is ``DQPSK`` layer B has to be ``DQPSK``. If layer B is +``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ =0 layer has to be +``DQPSK``. + + +.. _DTV-ISDBT-LAYER-SEGMENT-COUNT: + +DTV_ISDBT_LAYER*_SEGMENT_COUNT +------------------------------ + +Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO) + +Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and +``DTV_ISDBT_PARTIAL_RECEPTION`` and ``LAYER`` *_SEGMENT_COUNT + + +.. _isdbt-layer_seg-cnt-table: + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - PR + + - SB + + - Layer A width + + - Layer B width + + - Layer C width + + - total width + + - .. row 2 + + - 0 + + - 0 + + - 1 .. 13 + + - 1 .. 13 + + - 1 .. 13 + + - 13 + + - .. row 3 + + - 1 + + - 0 + + - 1 + + - 1 .. 13 + + - 1 .. 13 + + - 13 + + - .. row 4 + + - 0 + + - 1 + + - 1 + + - 0 + + - 0 + + - 1 + + - .. row 5 + + - 1 + + - 1 + + - 1 + + - 2 + + - 0 + + - 13 + + + +.. _DTV-ISDBT-LAYER-TIME-INTERLEAVING: + +DTV_ISDBT_LAYER*_TIME_INTERLEAVING +---------------------------------- + +Valid values: 0, 1, 2, 4, -1 (AUTO) + +when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid. + +Note: The real time interleaving length depends on the mode (fft-size). +The values here are referring to what can be found in the +TMCC-structure, as shown in the table below. + + +.. _isdbt-layer-interleaving-table: + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - DTV_ISDBT_LAYER*_TIME_INTERLEAVING + + - Mode 1 (2K FFT) + + - Mode 2 (4K FFT) + + - Mode 3 (8K FFT) + + - .. row 2 + + - 0 + + - 0 + + - 0 + + - 0 + + - .. row 3 + + - 1 + + - 4 + + - 2 + + - 1 + + - .. row 4 + + - 2 + + - 8 + + - 4 + + - 2 + + - .. row 5 + + - 4 + + - 16 + + - 8 + + - 4 + + + +.. _DTV-ATSCMH-FIC-VER: + +DTV_ATSCMH_FIC_VER +------------------ + +Version number of the FIC (Fast Information Channel) signaling data. + +FIC is used for relaying information to allow rapid service acquisition +by the receiver. + +Possible values: 0, 1, 2, 3, ..., 30, 31 + + +.. _DTV-ATSCMH-PARADE-ID: + +DTV_ATSCMH_PARADE_ID +-------------------- + +Parade identification number + +A parade is a collection of up to eight MH groups, conveying one or two +ensembles. + +Possible values: 0, 1, 2, 3, ..., 126, 127 + + +.. _DTV-ATSCMH-NOG: + +DTV_ATSCMH_NOG +-------------- + +Number of MH groups per MH subframe for a designated parade. + +Possible values: 1, 2, 3, 4, 5, 6, 7, 8 + + +.. _DTV-ATSCMH-TNOG: + +DTV_ATSCMH_TNOG +--------------- + +Total number of MH groups including all MH groups belonging to all MH +parades in one MH subframe. + +Possible values: 0, 1, 2, 3, ..., 30, 31 + + +.. _DTV-ATSCMH-SGN: + +DTV_ATSCMH_SGN +-------------- + +Start group number. + +Possible values: 0, 1, 2, 3, ..., 14, 15 + + +.. _DTV-ATSCMH-PRC: + +DTV_ATSCMH_PRC +-------------- + +Parade repetition cycle. + +Possible values: 1, 2, 3, 4, 5, 6, 7, 8 + + +.. _DTV-ATSCMH-RS-FRAME-MODE: + +DTV_ATSCMH_RS_FRAME_MODE +------------------------ + +Reed Solomon (RS) frame mode. + +Possible values are: + + +.. _atscmh-rs-frame-mode: + +.. flat-table:: enum atscmh_rs_frame_mode + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`ATSCMH-RSFRAME-PRI-ONLY`: + + ``ATSCMH_RSFRAME_PRI_ONLY`` + + - Single Frame: There is only a primary RS Frame for all Group + Regions. + + - .. row 3 + + - .. _`ATSCMH-RSFRAME-PRI-SEC`: + + ``ATSCMH_RSFRAME_PRI_SEC`` + + - Dual Frame: There are two separate RS Frames: Primary RS Frame for + Group Region A and B and Secondary RS Frame for Group Region C and + D. + + + +.. _DTV-ATSCMH-RS-FRAME-ENSEMBLE: + +DTV_ATSCMH_RS_FRAME_ENSEMBLE +---------------------------- + +Reed Solomon(RS) frame ensemble. + +Possible values are: + + +.. _atscmh-rs-frame-ensemble: + +.. flat-table:: enum atscmh_rs_frame_ensemble + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`ATSCMH-RSFRAME-ENS-PRI`: + + ``ATSCMH_RSFRAME_ENS_PRI`` + + - Primary Ensemble. + + - .. row 3 + + - .. _`ATSCMH-RSFRAME-ENS-SEC`: + + ``AATSCMH_RSFRAME_PRI_SEC`` + + - Secondary Ensemble. + + - .. row 4 + + - .. _`ATSCMH-RSFRAME-RES`: + + ``AATSCMH_RSFRAME_RES`` + + - Reserved. Shouldn't be used. + + + +.. _DTV-ATSCMH-RS-CODE-MODE-PRI: + +DTV_ATSCMH_RS_CODE_MODE_PRI +--------------------------- + +Reed Solomon (RS) code mode (primary). + +Possible values are: + + +.. _atscmh-rs-code-mode: + +.. flat-table:: enum atscmh_rs_code_mode + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`ATSCMH-RSCODE-211-187`: + + ``ATSCMH_RSCODE_211_187`` + + - Reed Solomon code (211,187). + + - .. row 3 + + - .. _`ATSCMH-RSCODE-223-187`: + + ``ATSCMH_RSCODE_223_187`` + + - Reed Solomon code (223,187). + + - .. row 4 + + - .. _`ATSCMH-RSCODE-235-187`: + + ``ATSCMH_RSCODE_235_187`` + + - Reed Solomon code (235,187). + + - .. row 5 + + - .. _`ATSCMH-RSCODE-RES`: + + ``ATSCMH_RSCODE_RES`` + + - Reserved. Shouldn't be used. + + + +.. _DTV-ATSCMH-RS-CODE-MODE-SEC: + +DTV_ATSCMH_RS_CODE_MODE_SEC +--------------------------- + +Reed Solomon (RS) code mode (secondary). + +Possible values are the same as documented on enum +:ref:`atscmh_rs_code_mode `: + + +.. _DTV-ATSCMH-SCCC-BLOCK-MODE: + +DTV_ATSCMH_SCCC_BLOCK_MODE +-------------------------- + +Series Concatenated Convolutional Code Block Mode. + +Possible values are: + + +.. _atscmh-sccc-block-mode: + +.. flat-table:: enum atscmh_scc_block_mode + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`ATSCMH-SCCC-BLK-SEP`: + + ``ATSCMH_SCCC_BLK_SEP`` + + - Separate SCCC: the SCCC outer code mode shall be set independently + for each Group Region (A, B, C, D) + + - .. row 3 + + - .. _`ATSCMH-SCCC-BLK-COMB`: + + ``ATSCMH_SCCC_BLK_COMB`` + + - Combined SCCC: all four Regions shall have the same SCCC outer + code mode. + + - .. row 4 + + - .. _`ATSCMH-SCCC-BLK-RES`: + + ``ATSCMH_SCCC_BLK_RES`` + + - Reserved. Shouldn't be used. + + + +.. _DTV-ATSCMH-SCCC-CODE-MODE-A: + +DTV_ATSCMH_SCCC_CODE_MODE_A +--------------------------- + +Series Concatenated Convolutional Code Rate. + +Possible values are: + + +.. _atscmh-sccc-code-mode: + +.. flat-table:: enum atscmh_sccc_code_mode + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`ATSCMH-SCCC-CODE-HLF`: + + ``ATSCMH_SCCC_CODE_HLF`` + + - The outer code rate of a SCCC Block is 1/2 rate. + + - .. row 3 + + - .. _`ATSCMH-SCCC-CODE-QTR`: + + ``ATSCMH_SCCC_CODE_QTR`` + + - The outer code rate of a SCCC Block is 1/4 rate. + + - .. row 4 + + - .. _`ATSCMH-SCCC-CODE-RES`: + + ``ATSCMH_SCCC_CODE_RES`` + + - to be documented. + + + +.. _DTV-ATSCMH-SCCC-CODE-MODE-B: + +DTV_ATSCMH_SCCC_CODE_MODE_B +--------------------------- + +Series Concatenated Convolutional Code Rate. + +Possible values are the same as documented on enum +:ref:`atscmh_sccc_code_mode `. + + +.. _DTV-ATSCMH-SCCC-CODE-MODE-C: + +DTV_ATSCMH_SCCC_CODE_MODE_C +--------------------------- + +Series Concatenated Convolutional Code Rate. + +Possible values are the same as documented on enum +:ref:`atscmh_sccc_code_mode `. + + +.. _DTV-ATSCMH-SCCC-CODE-MODE-D: + +DTV_ATSCMH_SCCC_CODE_MODE_D +--------------------------- + +Series Concatenated Convolutional Code Rate. + +Possible values are the same as documented on enum +:ref:`atscmh_sccc_code_mode `. + + +.. _DTV-API-VERSION: + +DTV_API_VERSION +=============== + +Returns the major/minor version of the DVB API + + +.. _DTV-CODE-RATE-HP: + +DTV_CODE_RATE_HP +================ + +Used on terrestrial transmissions. The acceptable values are the ones +described at :ref:`fe_transmit_mode_t `. + + +.. _DTV-CODE-RATE-LP: + +DTV_CODE_RATE_LP +================ + +Used on terrestrial transmissions. The acceptable values are the ones +described at :ref:`fe_transmit_mode_t `. + + +.. _DTV-GUARD-INTERVAL: + +DTV_GUARD_INTERVAL +================== + +Possible values are: + + +.. _fe-guard-interval-t: + +Modulation guard interval +------------------------- + + +.. _fe-guard-interval: + +.. flat-table:: enum fe_guard_interval + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`GUARD-INTERVAL-AUTO`: + + ``GUARD_INTERVAL_AUTO`` + + - Autodetect the guard interval + + - .. row 3 + + - .. _`GUARD-INTERVAL-1-128`: + + ``GUARD_INTERVAL_1_128`` + + - Guard interval 1/128 + + - .. row 4 + + - .. _`GUARD-INTERVAL-1-32`: + + ``GUARD_INTERVAL_1_32`` + + - Guard interval 1/32 + + - .. row 5 + + - .. _`GUARD-INTERVAL-1-16`: + + ``GUARD_INTERVAL_1_16`` + + - Guard interval 1/16 + + - .. row 6 + + - .. _`GUARD-INTERVAL-1-8`: + + ``GUARD_INTERVAL_1_8`` + + - Guard interval 1/8 + + - .. row 7 + + - .. _`GUARD-INTERVAL-1-4`: + + ``GUARD_INTERVAL_1_4`` + + - Guard interval 1/4 + + - .. row 8 + + - .. _`GUARD-INTERVAL-19-128`: + + ``GUARD_INTERVAL_19_128`` + + - Guard interval 19/128 + + - .. row 9 + + - .. _`GUARD-INTERVAL-19-256`: + + ``GUARD_INTERVAL_19_256`` + + - Guard interval 19/256 + + - .. row 10 + + - .. _`GUARD-INTERVAL-PN420`: + + ``GUARD_INTERVAL_PN420`` + + - PN length 420 (1/4) + + - .. row 11 + + - .. _`GUARD-INTERVAL-PN595`: + + ``GUARD_INTERVAL_PN595`` + + - PN length 595 (1/6) + + - .. row 12 + + - .. _`GUARD-INTERVAL-PN945`: + + ``GUARD_INTERVAL_PN945`` + + - PN length 945 (1/9) + + +Notes: + +1) If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the +hardware will try to find the correct guard interval (if capable) and +will use TMCC to fill in the missing parameters. + +2) Intervals 1/128, 19/128 and 19/256 are used only for DVB-T2 at +present + +3) DTMB specifies PN420, PN595 and PN945. + + +.. _DTV-TRANSMISSION-MODE: + +DTV_TRANSMISSION_MODE +===================== + +Specifies the number of carriers used by the standard. This is used only +on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB + + +.. _fe-transmit-mode-t: + +enum fe_transmit_mode: Number of carriers per channel +----------------------------------------------------- + + +.. _fe-transmit-mode: + +.. flat-table:: enum fe_transmit_mode + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`TRANSMISSION-MODE-AUTO`: + + ``TRANSMISSION_MODE_AUTO`` + + - Autodetect transmission mode. The hardware will try to find the + correct FFT-size (if capable) to fill in the missing parameters. + + - .. row 3 + + - .. _`TRANSMISSION-MODE-1K`: + + ``TRANSMISSION_MODE_1K`` + + - Transmission mode 1K + + - .. row 4 + + - .. _`TRANSMISSION-MODE-2K`: + + ``TRANSMISSION_MODE_2K`` + + - Transmission mode 2K + + - .. row 5 + + - .. _`TRANSMISSION-MODE-8K`: + + ``TRANSMISSION_MODE_8K`` + + - Transmission mode 8K + + - .. row 6 + + - .. _`TRANSMISSION-MODE-4K`: + + ``TRANSMISSION_MODE_4K`` + + - Transmission mode 4K + + - .. row 7 + + - .. _`TRANSMISSION-MODE-16K`: + + ``TRANSMISSION_MODE_16K`` + + - Transmission mode 16K + + - .. row 8 + + - .. _`TRANSMISSION-MODE-32K`: + + ``TRANSMISSION_MODE_32K`` + + - Transmission mode 32K + + - .. row 9 + + - .. _`TRANSMISSION-MODE-C1`: + + ``TRANSMISSION_MODE_C1`` + + - Single Carrier (C=1) transmission mode (DTMB) + + - .. row 10 + + - .. _`TRANSMISSION-MODE-C3780`: + + ``TRANSMISSION_MODE_C3780`` + + - Multi Carrier (C=3780) transmission mode (DTMB) + + +Notes: + +1) ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called +'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K + +2) If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO`` +the hardware will try to find the correct FFT-size (if capable) and will +use TMCC to fill in the missing parameters. + +3) DVB-T specifies 2K and 8K as valid sizes. + +4) DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K. + +5) DTMB specifies C1 and C3780. + + +.. _DTV-HIERARCHY: + +DTV_HIERARCHY +============= + +Frontend hierarchy + + +.. _fe-hierarchy-t: + +Frontend hierarchy +------------------ + + +.. _fe-hierarchy: + +.. flat-table:: enum fe_hierarchy + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`HIERARCHY-NONE`: + + ``HIERARCHY_NONE`` + + - No hierarchy + + - .. row 3 + + - .. _`HIERARCHY-AUTO`: + + ``HIERARCHY_AUTO`` + + - Autodetect hierarchy (if supported) + + - .. row 4 + + - .. _`HIERARCHY-1`: + + ``HIERARCHY_1`` + + - Hierarchy 1 + + - .. row 5 + + - .. _`HIERARCHY-2`: + + ``HIERARCHY_2`` + + - Hierarchy 2 + + - .. row 6 + + - .. _`HIERARCHY-4`: + + ``HIERARCHY_4`` + + - Hierarchy 4 + + + +.. _DTV-STREAM-ID: + +DTV_STREAM_ID +============= + +DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on +a single transport stream. This property enables the DVB driver to +handle substream filtering, when supported by the hardware. By default, +substream filtering is disabled. + +For DVB-S2 and DVB-T2, the valid substream id range is from 0 to 255. + +For ISDB, the valid substream id range is from 1 to 65535. + +To disable it, you should use the special macro NO_STREAM_ID_FILTER. + +Note: any value outside the id range also disables filtering. + + +.. _DTV-DVBT2-PLP-ID-LEGACY: + +DTV_DVBT2_PLP_ID_LEGACY +======================= + +Obsolete, replaced with DTV_STREAM_ID. + + +.. _DTV-ENUM-DELSYS: + +DTV_ENUM_DELSYS +=============== + +A Multi standard frontend needs to advertise the delivery systems +provided. Applications need to enumerate the provided delivery systems, +before using any other operation with the frontend. Prior to it's +introduction, FE_GET_INFO was used to determine a frontend type. A +frontend which provides more than a single delivery system, +FE_GET_INFO doesn't help much. Applications which intends to use a +multistandard frontend must enumerate the delivery systems associated +with it, rather than trying to use FE_GET_INFO. In the case of a +legacy frontend, the result is just the same as with FE_GET_INFO, but +in a more structured format + + +.. _DTV-INTERLEAVING: + +DTV_INTERLEAVING +================ + +Time interleaving to be used. Currently, used only on DTMB. + + +.. _fe-interleaving: + +.. flat-table:: enum fe_interleaving + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - .. _`INTERLEAVING-NONE`: + + ``INTERLEAVING_NONE`` + + - No interleaving. + + - .. row 3 + + - .. _`INTERLEAVING-AUTO`: + + ``INTERLEAVING_AUTO`` + + - Auto-detect interleaving. + + - .. row 4 + + - .. _`INTERLEAVING-240`: + + ``INTERLEAVING_240`` + + - Interleaving of 240 symbols. + + - .. row 5 + + - .. _`INTERLEAVING-720`: + + ``INTERLEAVING_720`` + + - Interleaving of 720 symbols. + + + +.. _DTV-LNA: + +DTV_LNA +======= + +Low-noise amplifier. + +Hardware might offer controllable LNA which can be set manually using +that parameter. Usually LNA could be found only from terrestrial devices +if at all. + +Possible values: 0, 1, LNA_AUTO + +0, LNA off + +1, LNA on + +use the special macro LNA_AUTO to set LNA auto + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend-property-cable-systems.rst b/Documentation/linux_tv/media/dvb/frontend-property-cable-systems.rst new file mode 100644 index 000000000000..360966ef50cf --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend-property-cable-systems.rst @@ -0,0 +1,84 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend-property-cable-systems: + +***************************************** +Properties used on cable delivery systems +***************************************** + + +.. _dvbc-params: + +DVB-C delivery system +===================== + +The DVB-C Annex-A is the widely used cable standard. Transmission uses +QAM modulation. + +The DVB-C Annex-C is optimized for 6MHz, and is used in Japan. It +supports a subset of the Annex A modulation types, and a roll-off of +0.13, instead of 0.15 + +The following parameters are valid for DVB-C Annex A/C: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_SYMBOL_RATE ` + +- :ref:`DTV_INNER_FEC ` + +- :ref:`DTV_LNA ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _dvbc-annex-b-params: + +DVB-C Annex B delivery system +============================= + +The DVB-C Annex-B is only used on a few Countries like the United +States. + +The following parameters are valid for DVB-C Annex B: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_LNA ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend-property-satellite-systems.rst b/Documentation/linux_tv/media/dvb/frontend-property-satellite-systems.rst new file mode 100644 index 000000000000..1a204ac01afd --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend-property-satellite-systems.rst @@ -0,0 +1,112 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend-property-satellite-systems: + +********************************************* +Properties used on satellite delivery systems +********************************************* + + +.. _dvbs-params: + +DVB-S delivery system +===================== + +The following parameters are valid for DVB-S: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_SYMBOL_RATE ` + +- :ref:`DTV_INNER_FEC ` + +- :ref:`DTV_VOLTAGE ` + +- :ref:`DTV_TONE ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + +Future implementations might add those two missing parameters: + +- :ref:`DTV_DISEQC_MASTER ` + +- :ref:`DTV_DISEQC_SLAVE_REPLY ` + + +.. _dvbs2-params: + +DVB-S2 delivery system +====================== + +In addition to all parameters valid for DVB-S, DVB-S2 supports the +following parameters: + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_PILOT ` + +- :ref:`DTV_ROLLOFF ` + +- :ref:`DTV_STREAM_ID ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _turbo-params: + +Turbo code delivery system +========================== + +In addition to all parameters valid for DVB-S, turbo code supports the +following parameters: + +- :ref:`DTV_MODULATION ` + + +.. _isdbs-params: + +ISDB-S delivery system +====================== + +The following parameters are valid for ISDB-S: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_SYMBOL_RATE ` + +- :ref:`DTV_INNER_FEC ` + +- :ref:`DTV_VOLTAGE ` + +- :ref:`DTV_STREAM_ID ` + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend-property-terrestrial-systems.rst b/Documentation/linux_tv/media/dvb/frontend-property-terrestrial-systems.rst new file mode 100644 index 000000000000..78026596f46f --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend-property-terrestrial-systems.rst @@ -0,0 +1,303 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend-property-terrestrial-systems: + +*********************************************** +Properties used on terrestrial delivery systems +*********************************************** + + +.. _dvbt-params: + +DVB-T delivery system +===================== + +The following parameters are valid for DVB-T: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_BANDWIDTH_HZ ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_CODE_RATE_HP ` + +- :ref:`DTV_CODE_RATE_LP ` + +- :ref:`DTV_GUARD_INTERVAL ` + +- :ref:`DTV_TRANSMISSION_MODE ` + +- :ref:`DTV_HIERARCHY ` + +- :ref:`DTV_LNA ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _dvbt2-params: + +DVB-T2 delivery system +====================== + +DVB-T2 support is currently in the early stages of development, so +expect that this section maygrow and become more detailed with time. + +The following parameters are valid for DVB-T2: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_BANDWIDTH_HZ ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_CODE_RATE_HP ` + +- :ref:`DTV_CODE_RATE_LP ` + +- :ref:`DTV_GUARD_INTERVAL ` + +- :ref:`DTV_TRANSMISSION_MODE ` + +- :ref:`DTV_HIERARCHY ` + +- :ref:`DTV_STREAM_ID ` + +- :ref:`DTV_LNA ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _isdbt: + +ISDB-T delivery system +====================== + +This ISDB-T/ISDB-Tsb API extension should reflect all information needed +to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible that some +very sophisticated devices won't need certain parameters to tune. + +The information given here should help application writers to know how +to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API. + +The details given here about ISDB-T and ISDB-Tsb are just enough to +basically show the dependencies between the needed parameter values, but +surely some information is left out. For more detailed information see +the following documents: + +ARIB STD-B31 - "Transmission System for Digital Terrestrial Television +Broadcasting" and + +ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial Television +Broadcasting". + +In order to understand the ISDB specific parameters, one has to have +some knowledge the channel structure in ISDB-T and ISDB-Tsb. I.e. it has +to be known to the reader that an ISDB-T channel consists of 13 +segments, that it can have up to 3 layer sharing those segments, and +things like that. + +The following parameters are valid for ISDB-T: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_BANDWIDTH_HZ ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_GUARD_INTERVAL ` + +- :ref:`DTV_TRANSMISSION_MODE ` + +- :ref:`DTV_ISDBT_LAYER_ENABLED ` + +- :ref:`DTV_ISDBT_PARTIAL_RECEPTION ` + +- :ref:`DTV_ISDBT_SOUND_BROADCASTING ` + +- :ref:`DTV_ISDBT_SB_SUBCHANNEL_ID ` + +- :ref:`DTV_ISDBT_SB_SEGMENT_IDX ` + +- :ref:`DTV_ISDBT_SB_SEGMENT_COUNT ` + +- :ref:`DTV_ISDBT_LAYERA_FEC ` + +- :ref:`DTV_ISDBT_LAYERA_MODULATION ` + +- :ref:`DTV_ISDBT_LAYERA_SEGMENT_COUNT ` + +- :ref:`DTV_ISDBT_LAYERA_TIME_INTERLEAVING ` + +- :ref:`DTV_ISDBT_LAYERB_FEC ` + +- :ref:`DTV_ISDBT_LAYERB_MODULATION ` + +- :ref:`DTV_ISDBT_LAYERB_SEGMENT_COUNT ` + +- :ref:`DTV_ISDBT_LAYERB_TIME_INTERLEAVING ` + +- :ref:`DTV_ISDBT_LAYERC_FEC ` + +- :ref:`DTV_ISDBT_LAYERC_MODULATION ` + +- :ref:`DTV_ISDBT_LAYERC_SEGMENT_COUNT ` + +- :ref:`DTV_ISDBT_LAYERC_TIME_INTERLEAVING ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _atsc-params: + +ATSC delivery system +==================== + +The following parameters are valid for ATSC: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_BANDWIDTH_HZ ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _atscmh-params: + +ATSC-MH delivery system +======================= + +The following parameters are valid for ATSC-MH: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_BANDWIDTH_HZ ` + +- :ref:`DTV_ATSCMH_FIC_VER ` + +- :ref:`DTV_ATSCMH_PARADE_ID ` + +- :ref:`DTV_ATSCMH_NOG ` + +- :ref:`DTV_ATSCMH_TNOG ` + +- :ref:`DTV_ATSCMH_SGN ` + +- :ref:`DTV_ATSCMH_PRC ` + +- :ref:`DTV_ATSCMH_RS_FRAME_MODE ` + +- :ref:`DTV_ATSCMH_RS_FRAME_ENSEMBLE ` + +- :ref:`DTV_ATSCMH_RS_CODE_MODE_PRI ` + +- :ref:`DTV_ATSCMH_RS_CODE_MODE_SEC ` + +- :ref:`DTV_ATSCMH_SCCC_BLOCK_MODE ` + +- :ref:`DTV_ATSCMH_SCCC_CODE_MODE_A ` + +- :ref:`DTV_ATSCMH_SCCC_CODE_MODE_B ` + +- :ref:`DTV_ATSCMH_SCCC_CODE_MODE_C ` + +- :ref:`DTV_ATSCMH_SCCC_CODE_MODE_D ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. _dtmb-params: + +DTMB delivery system +==================== + +The following parameters are valid for DTMB: + +- :ref:`DTV_API_VERSION ` + +- :ref:`DTV_DELIVERY_SYSTEM ` + +- :ref:`DTV_TUNE ` + +- :ref:`DTV_CLEAR ` + +- :ref:`DTV_FREQUENCY ` + +- :ref:`DTV_MODULATION ` + +- :ref:`DTV_BANDWIDTH_HZ ` + +- :ref:`DTV_INVERSION ` + +- :ref:`DTV_INNER_FEC ` + +- :ref:`DTV_GUARD_INTERVAL ` + +- :ref:`DTV_TRANSMISSION_MODE ` + +- :ref:`DTV_INTERLEAVING ` + +- :ref:`DTV_LNA ` + +In addition, the :ref:`DTV QoS statistics ` +are also valid. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend-stat-properties.rst b/Documentation/linux_tv/media/dvb/frontend-stat-properties.rst new file mode 100644 index 000000000000..36461d65a661 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend-stat-properties.rst @@ -0,0 +1,254 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend-stat-properties: + +****************************** +Frontend statistics indicators +****************************** + +The values are returned via ``dtv_property.stat``. If the property is +supported, ``dtv_property.stat.len`` is bigger than zero. + +For most delivery systems, ``dtv_property.stat.len`` will be 1 if the +stats is supported, and the properties will return a single value for +each parameter. + +It should be noted, however, that new OFDM delivery systems like ISDB +can use different modulation types for each group of carriers. On such +standards, up to 3 groups of statistics can be provided, and +``dtv_property.stat.len`` is updated to reflect the "global" metrics, +plus one metric per each carrier group (called "layer" on ISDB). + +So, in order to be consistent with other delivery systems, the first +value at :ref:`dtv_property.stat.dtv_stats ` array refers +to the global metric. The other elements of the array represent each +layer, starting from layer A(index 1), layer B (index 2) and so on. + +The number of filled elements are stored at ``dtv_property.stat.len``. + +Each element of the ``dtv_property.stat.dtv_stats`` array consists on +two elements: + +- ``svalue`` or ``uvalue``, where ``svalue`` is for signed values of + the measure (dB measures) and ``uvalue`` is for unsigned values + (counters, relative scale) + +- ``scale`` - Scale for the value. It can be: + + - ``FE_SCALE_NOT_AVAILABLE`` - The parameter is supported by the + frontend, but it was not possible to collect it (could be a + transitory or permanent condition) + + - ``FE_SCALE_DECIBEL`` - parameter is a signed value, measured in + 1/1000 dB + + - ``FE_SCALE_RELATIVE`` - parameter is a unsigned value, where 0 + means 0% and 65535 means 100%. + + - ``FE_SCALE_COUNTER`` - parameter is a unsigned value that counts + the occurrence of an event, like bit error, block error, or lapsed + time. + + +.. _DTV-STAT-SIGNAL-STRENGTH: + +DTV_STAT_SIGNAL_STRENGTH +======================== + +Indicates the signal strength level at the analog part of the tuner or +of the demod. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_DECIBEL`` - signal strength is in 0.001 dBm units, power + measured in miliwatts. This value is generally negative. + +- ``FE_SCALE_RELATIVE`` - The frontend provides a 0% to 100% + measurement for power (actually, 0 to 65535). + + +.. _DTV-STAT-CNR: + +DTV_STAT_CNR +============ + +Indicates the Signal to Noise ratio for the main carrier. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_DECIBEL`` - Signal/Noise ratio is in 0.001 dB units. + +- ``FE_SCALE_RELATIVE`` - The frontend provides a 0% to 100% + measurement for Signal/Noise (actually, 0 to 65535). + + +.. _DTV-STAT-PRE-ERROR-BIT-COUNT: + +DTV_STAT_PRE_ERROR_BIT_COUNT +============================ + +Measures the number of bit errors before the forward error correction +(FEC) on the inner coding block (before Viterbi, LDPC or other inner +code). + +This measure is taken during the same interval as +``DTV_STAT_PRE_TOTAL_BIT_COUNT``. + +In order to get the BER (Bit Error Rate) measurement, it should be +divided by +:ref:`DTV_STAT_PRE_TOTAL_BIT_COUNT `. + +This measurement is monotonically increased, as the frontend gets more +bit count measurements. The frontend may reset it when a +channel/transponder is tuned. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_COUNTER`` - Number of error bits counted before the inner + coding. + + +.. _DTV-STAT-PRE-TOTAL-BIT-COUNT: + +DTV_STAT_PRE_TOTAL_BIT_COUNT +============================ + +Measures the amount of bits received before the inner code block, during +the same period as +:ref:`DTV_STAT_PRE_ERROR_BIT_COUNT ` +measurement was taken. + +It should be noted that this measurement can be smaller than the total +amount of bits on the transport stream, as the frontend may need to +manually restart the measurement, losing some data between each +measurement interval. + +This measurement is monotonically increased, as the frontend gets more +bit count measurements. The frontend may reset it when a +channel/transponder is tuned. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_COUNTER`` - Number of bits counted while measuring + :ref:`DTV_STAT_PRE_ERROR_BIT_COUNT `. + + +.. _DTV-STAT-POST-ERROR-BIT-COUNT: + +DTV_STAT_POST_ERROR_BIT_COUNT +============================= + +Measures the number of bit errors after the forward error correction +(FEC) done by inner code block (after Viterbi, LDPC or other inner +code). + +This measure is taken during the same interval as +``DTV_STAT_POST_TOTAL_BIT_COUNT``. + +In order to get the BER (Bit Error Rate) measurement, it should be +divided by +:ref:`DTV_STAT_POST_TOTAL_BIT_COUNT `. + +This measurement is monotonically increased, as the frontend gets more +bit count measurements. The frontend may reset it when a +channel/transponder is tuned. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_COUNTER`` - Number of error bits counted after the inner + coding. + + +.. _DTV-STAT-POST-TOTAL-BIT-COUNT: + +DTV_STAT_POST_TOTAL_BIT_COUNT +============================= + +Measures the amount of bits received after the inner coding, during the +same period as +:ref:`DTV_STAT_POST_ERROR_BIT_COUNT ` +measurement was taken. + +It should be noted that this measurement can be smaller than the total +amount of bits on the transport stream, as the frontend may need to +manually restart the measurement, losing some data between each +measurement interval. + +This measurement is monotonically increased, as the frontend gets more +bit count measurements. The frontend may reset it when a +channel/transponder is tuned. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_COUNTER`` - Number of bits counted while measuring + :ref:`DTV_STAT_POST_ERROR_BIT_COUNT `. + + +.. _DTV-STAT-ERROR-BLOCK-COUNT: + +DTV_STAT_ERROR_BLOCK_COUNT +========================== + +Measures the number of block errors after the outer forward error +correction coding (after Reed-Solomon or other outer code). + +This measurement is monotonically increased, as the frontend gets more +bit count measurements. The frontend may reset it when a +channel/transponder is tuned. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_COUNTER`` - Number of error blocks counted after the outer + coding. + + +.. _DTV-STAT-TOTAL-BLOCK-COUNT: + +DTV-STAT_TOTAL_BLOCK_COUNT +========================== + +Measures the total number of blocks received during the same period as +:ref:`DTV_STAT_ERROR_BLOCK_COUNT ` +measurement was taken. + +It can be used to calculate the PER indicator, by dividing +:ref:`DTV_STAT_ERROR_BLOCK_COUNT ` by +:ref:`DTV-STAT-TOTAL-BLOCK-COUNT `. + +Possible scales for this metric are: + +- ``FE_SCALE_NOT_AVAILABLE`` - it failed to measure it, or the + measurement was not complete yet. + +- ``FE_SCALE_COUNTER`` - Number of blocks counted while measuring + :ref:`DTV_STAT_ERROR_BLOCK_COUNT `. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend.rst b/Documentation/linux_tv/media/dvb/frontend.rst new file mode 100644 index 000000000000..46be409e76b6 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend.rst @@ -0,0 +1,62 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_frontend: + +################ +DVB Frontend API +################ +The DVB frontend API was designed to support three types of delivery +systems: + +- Terrestrial systems: DVB-T, DVB-T2, ATSC, ATSC M/H, ISDB-T, DVB-H, + DTMB, CMMB + +- Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B), ISDB-C + +- Satellite systems: DVB-S, DVB-S2, DVB Turbo, ISDB-S, DSS + +The DVB frontend controls several sub-devices including: + +- Tuner + +- Digital TV demodulator + +- Low noise amplifier (LNA) + +- Satellite Equipment Control (SEC) hardware (only for Satellite). + +The frontend can be accessed through ``/dev/dvb/adapter?/frontend?``. +Data types and ioctl definitions can be accessed by including +``linux/dvb/frontend.h`` in your application. + +NOTE: Transmission via the internet (DVB-IP) is not yet handled by this +API but a future extension is possible. + +On Satellite systems, the API support for the Satellite Equipment +Control (SEC) allows to power control and to send/receive signals to +control the antenna subsystem, selecting the polarization and choosing +the Intermediate Frequency IF) of the Low Noise Block Converter Feed +Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC +(digital SEC) specification is available at +`Eutelsat `__. + + +.. toctree:: + :maxdepth: 1 + + query-dvb-frontend-info + dvb-fe-read-status + dvbproperty + frontend_fcalls + frontend_legacy_dvbv3_api + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend_f_close.rst b/Documentation/linux_tv/media/dvb/frontend_f_close.rst new file mode 100644 index 000000000000..cde87322859a --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend_f_close.rst @@ -0,0 +1,55 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend_f_close: + +******************** +DVB frontend close() +******************** + +*man fe-close(2)* + +Close a frontend device + + +Synopsis +======== + +.. code-block:: c + + #include + + +.. c:function:: int close( int fd ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + + +Description +=========== + +This system call closes a previously opened front-end device. After +closing a front-end device, its corresponding hardware might be powered +down automatically. + + +Return Value +============ + +The function returns 0 on success, -1 on failure and the ``errno`` is +set appropriately. Possible error codes: + +EBADF + ``fd`` is not a valid open file descriptor. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend_f_open.rst b/Documentation/linux_tv/media/dvb/frontend_f_open.rst new file mode 100644 index 000000000000..676ae922338d --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend_f_open.rst @@ -0,0 +1,108 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend_f_open: + +******************* +DVB frontend open() +******************* + +*man fe-open(2)* + +Open a frontend device + + +Synopsis +======== + +.. code-block:: c + + #include + + +.. c:function:: int open( const char *device_name, int flags ) + +Arguments +========= + +``device_name`` + Device to be opened. + +``flags`` + Open flags. Access can either be ``O_RDWR`` or ``O_RDONLY``. + + Multiple opens are allowed with ``O_RDONLY``. In this mode, only + query and read ioctls are allowed. + + Only one open is allowed in ``O_RDWR``. In this mode, all ioctls are + allowed. + + When the ``O_NONBLOCK`` flag is given, the system calls may return + EAGAIN error code when no data is available or when the device + driver is temporarily busy. + + Other flags have no effect. + + +Description +=========== + +This system call opens a named frontend device +(``/dev/dvb/adapter?/frontend?``) for subsequent use. Usually the first +thing to do after a successful open is to find out the frontend type +with :ref:`FE_GET_INFO `. + +The device can be opened in read-only mode, which only allows monitoring +of device status and statistics, or read/write mode, which allows any +kind of use (e.g. performing tuning operations.) + +In a system with multiple front-ends, it is usually the case that +multiple devices cannot be open in read/write mode simultaneously. As +long as a front-end device is opened in read/write mode, other open() +calls in read/write mode will either fail or block, depending on whether +non-blocking or blocking mode was specified. A front-end device opened +in blocking mode can later be put into non-blocking mode (and vice +versa) using the F_SETFL command of the fcntl system call. This is a +standard system call, documented in the Linux manual page for fcntl. +When an open() call has succeeded, the device will be ready for use in +the specified mode. This implies that the corresponding hardware is +powered up, and that other front-ends may have been powered down to make +that possible. + + +Return Value +============ + +On success :c:func:`open()` returns the new file descriptor. On error +-1 is returned, and the ``errno`` variable is set appropriately. +Possible error codes are: + +EACCES + The caller has no permission to access the device. + +EBUSY + The the device driver is already in use. + +ENXIO + No device corresponding to this device special file exists. + +ENOMEM + Not enough kernel memory was available to complete the request. + +EMFILE + The process already has the maximum number of files open. + +ENFILE + The limit on the total number of files open on the system has been + reached. + +ENODEV + The device got removed. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend_fcalls.rst b/Documentation/linux_tv/media/dvb/frontend_fcalls.rst new file mode 100644 index 000000000000..8eae0e9461ab --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend_fcalls.rst @@ -0,0 +1,35 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend_fcalls: + +####################### +Frontend Function Calls +####################### + +.. toctree:: + :maxdepth: 1 + + frontend_f_open + frontend_f_close + fe-get-info + fe-read-status + fe-get-property + fe-diseqc-reset-overload + fe-diseqc-send-master-cmd + fe-diseqc-recv-slave-reply + fe-diseqc-send-burst + fe-set-tone + fe-set-voltage + fe-enable-high-lnb-voltage + fe-set-frontend-tune-mode + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend_h.rst b/Documentation/linux_tv/media/dvb/frontend_h.rst new file mode 100644 index 000000000000..3f616c6bd01d --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend_h.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend_h: + +************************ +DVB Frontend Header File +************************ + + +.. toctree:: + :maxdepth: 1 + + ../../frontend.h + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend_legacy_api.rst b/Documentation/linux_tv/media/dvb/frontend_legacy_api.rst new file mode 100644 index 000000000000..dcc62d4a8516 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend_legacy_api.rst @@ -0,0 +1,49 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend_legacy_types: + +Frontend Legacy Data Types +========================== + + +.. toctree:: + :maxdepth: 1 + + fe-type-t + fe-bandwidth-t + dvb-frontend-parameters + dvb-frontend-event + + +.. _frontend_legacy_fcalls: + +Frontend Legacy Function Calls +============================== + +Those functions are defined at DVB version 3. The support is kept in the +kernel due to compatibility issues only. Their usage is strongly not +recommended + + +.. toctree:: + :maxdepth: 1 + + FE_READ_BER + FE_READ_SNR + FE_READ_SIGNAL_STRENGTH + FE_READ_UNCORRECTED_BLOCKS + FE_SET_FRONTEND + FE_GET_FRONTEND + FE_GET_EVENT + FE_DISHNETWORK_SEND_LEGACY_CMD + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/frontend_legacy_dvbv3_api.rst b/Documentation/linux_tv/media/dvb/frontend_legacy_dvbv3_api.rst new file mode 100644 index 000000000000..1dbff41f6a34 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/frontend_legacy_dvbv3_api.rst @@ -0,0 +1,29 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _frontend_legacy_dvbv3_api: + +**************************************** +DVB Frontend legacy API (a. k. a. DVBv3) +**************************************** + +The usage of this API is deprecated, as it doesn't support all digital +TV standards, doesn't provide good statistics measurements and provides +incomplete information. This is kept only to support legacy +applications. + + +.. toctree:: + :maxdepth: 1 + + frontend_legacy_api + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/intro.rst b/Documentation/linux_tv/media/dvb/intro.rst new file mode 100644 index 000000000000..0508f0d2c9db --- /dev/null +++ b/Documentation/linux_tv/media/dvb/intro.rst @@ -0,0 +1,204 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_introdution: + +************ +Introduction +************ + + +.. _requisites: + +What you need to know +===================== + +The reader of this document is required to have some knowledge in the +area of digital video broadcasting (DVB) and should be familiar with +part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e +you should know what a program/transport stream (PS/TS) is and what is +meant by a packetized elementary stream (PES) or an I-frame. + +Various DVB standards documents are available from http://www.dvb.org +and/or http://www.etsi.org. + +It is also necessary to know how to access unix/linux devices and how to +use ioctl calls. This also includes the knowledge of C or C++. + + +.. _history: + +History +======= + +The first API for DVB cards we used at Convergence in late 1999 was an +extension of the Video4Linux API which was primarily developed for frame +grabber cards. As such it was not really well suited to be used for DVB +cards and their new features like recording MPEG streams and filtering +several section and PES data streams at the same time. + +In early 2000, we were approached by Nokia with a proposal for a new +standard Linux DVB API. As a commitment to the development of terminals +based on open standards, Nokia and Convergence made it available to all +Linux developers and published it on https://linuxtv.org in September +2000. Convergence is the maintainer of the Linux DVB API. Together with +the LinuxTV community (i.e. you, the reader of this document), the Linux +DVB API will be constantly reviewed and improved. With the Linux driver +for the Siemens/Hauppauge DVB PCI card Convergence provides a first +implementation of the Linux DVB API. + + +.. _overview: + +Overview +======== + + +.. _stb_components: + +.. figure:: intro_files/dvbstb.* + :alt: dvbstb.pdf / dvbstb.png + :align: center + + Components of a DVB card/STB + +A DVB PCI card or DVB set-top-box (STB) usually consists of the +following main hardware components: + +- Frontend consisting of tuner and DVB demodulator + + Here the raw signal reaches the DVB hardware from a satellite dish or + antenna or directly from cable. The frontend down-converts and + demodulates this signal into an MPEG transport stream (TS). In case + of a satellite frontend, this includes a facility for satellite + equipment control (SEC), which allows control of LNB polarization, + multi feed switches or dish rotors. + +- Conditional Access (CA) hardware like CI adapters and smartcard slots + + The complete TS is passed through the CA hardware. Programs to which + the user has access (controlled by the smart card) are decoded in + real time and re-inserted into the TS. + +- Demultiplexer which filters the incoming DVB stream + + The demultiplexer splits the TS into its components like audio and + video streams. Besides usually several of such audio and video + streams it also contains data streams with information about the + programs offered in this or other streams of the same provider. + +- MPEG2 audio and video decoder + + The main targets of the demultiplexer are the MPEG2 audio and video + decoders. After decoding they pass on the uncompressed audio and + video to the computer screen or (through a PAL/NTSC encoder) to a TV + set. + +:ref:`stb_components` shows a crude schematic of the control and data +flow between those components. + +On a DVB PCI card not all of these have to be present since some +functionality can be provided by the main CPU of the PC (e.g. MPEG +picture and sound decoding) or is not needed (e.g. for data-only uses +like “internet over satellite”). Also not every card or STB provides +conditional access hardware. + + +.. _dvb_devices: + +Linux DVB Devices +================= + +The Linux DVB API lets you control these hardware components through +currently six Unix-style character devices for video, audio, frontend, +demux, CA and IP-over-DVB networking. The video and audio devices +control the MPEG2 decoder hardware, the frontend device the tuner and +the DVB demodulator. The demux device gives you control over the PES and +section filters of the hardware. If the hardware does not support +filtering these filters can be implemented in software. Finally, the CA +device controls all the conditional access capabilities of the hardware. +It can depend on the individual security requirements of the platform, +if and how many of the CA functions are made available to the +application through this device. + +All devices can be found in the ``/dev`` tree under ``/dev/dvb``. The +individual devices are called: + +- ``/dev/dvb/adapterN/audioM``, + +- ``/dev/dvb/adapterN/videoM``, + +- ``/dev/dvb/adapterN/frontendM``, + +- ``/dev/dvb/adapterN/netM``, + +- ``/dev/dvb/adapterN/demuxM``, + +- ``/dev/dvb/adapterN/dvrM``, + +- ``/dev/dvb/adapterN/caM``, + +where N enumerates the DVB PCI cards in a system starting from 0, and M +enumerates the devices of each type within each adapter, starting +from 0, too. We will omit the “ ``/dev/dvb/adapterN/``\ ” in the further +discussion of these devices. + +More details about the data structures and function calls of all the +devices are described in the following chapters. + + +.. _include_files: + +API include files +================= + +For each of the DVB devices a corresponding include file exists. The DVB +API include files should be included in application sources with a +partial path like: + + +.. code-block:: c + + #include + + +.. code-block:: c + + #include + + +.. code-block:: c + + #include + + +.. code-block:: c + + #include + + +.. code-block:: c + + #include + + +.. code-block:: c + + #include + + +.. code-block:: c + + #include + +To enable applications to support different API version, an additional +include file ``linux/dvb/version.h`` exists, which defines the constant +``DVB_API_VERSION``. This document describes ``DVB_API_VERSION 5.10``. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/intro_files/dvbstb.pdf b/Documentation/linux_tv/media/dvb/intro_files/dvbstb.pdf new file mode 100644 index 000000000000..0fa75d90c3eb Binary files /dev/null and b/Documentation/linux_tv/media/dvb/intro_files/dvbstb.pdf differ diff --git a/Documentation/linux_tv/media/dvb/intro_files/dvbstb.png b/Documentation/linux_tv/media/dvb/intro_files/dvbstb.png new file mode 100644 index 000000000000..9b8f372e7afd Binary files /dev/null and b/Documentation/linux_tv/media/dvb/intro_files/dvbstb.png differ diff --git a/Documentation/linux_tv/media/dvb/legacy_dvb_apis.rst b/Documentation/linux_tv/media/dvb/legacy_dvb_apis.rst new file mode 100644 index 000000000000..15e0d88c2866 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/legacy_dvb_apis.rst @@ -0,0 +1,31 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _legacy_dvb_apis: + +******************* +DVB Deprecated APIs +******************* + +The APIs described here are kept only for historical reasons. There's +just one driver for a very legacy hardware that uses this API. No modern +drivers should use it. Instead, audio and video should be using the V4L2 +and ALSA APIs, and the pipelines should be set using the Media +Controller API + + +.. toctree:: + :maxdepth: 1 + + video + audio + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/net.rst b/Documentation/linux_tv/media/dvb/net.rst new file mode 100644 index 000000000000..040ffc70601d --- /dev/null +++ b/Documentation/linux_tv/media/dvb/net.rst @@ -0,0 +1,219 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _net: + +############### +DVB Network API +############### +The DVB net device controls the mapping of data packages that are part +of a transport stream to be mapped into a virtual network interface, +visible through the standard Linux network protocol stack. + +Currently, two encapsulations are supported: + +- `Multi Protocol Encapsulation (MPE) `__ + +- `Ultra Lightweight Encapsulation (ULE) `__ + +In order to create the Linux virtual network interfaces, an application +needs to tell to the Kernel what are the PIDs and the encapsulation +types that are present on the transport stream. This is done through +``/dev/dvb/adapter?/net?`` device node. The data will be available via +virtual ``dvb?_?`` network interfaces, and will be controlled/routed via +the standard ip tools (like ip, route, netstat, ifconfig, etc). + +Data types and and ioctl definitions are defined via ``linux/dvb/net.h`` +header. + + +.. _net_fcalls: + +###################### +DVB net Function Calls +###################### + +.. _NET_ADD_IF: + +**************** +ioctl NET_ADD_IF +**************** + +*man NET_ADD_IF(2)* + +Creates a new network interface for a given Packet ID. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, struct dvb_net_if *net_if ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_TONE + +``net_if`` + pointer to struct :ref:`dvb_net_if ` + + +Description +=========== + +The NET_ADD_IF ioctl system call selects the Packet ID (PID) that +contains a TCP/IP traffic, the type of encapsulation to be used (MPE or +ULE) and the interface number for the new interface to be created. When +the system call successfully returns, a new virtual network interface is +created. + +The struct :ref:`dvb_net_if `::ifnum field will be +filled with the number of the created interface. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _dvb-net-if-t: + +struct dvb_net_if description +============================= + + +.. _dvb-net-if: + +.. flat-table:: struct dvb_net_if + :header-rows: 1 + :stub-columns: 0 + + + - .. row 1 + + - ID + + - Description + + - .. row 2 + + - pid + + - Packet ID (PID) of the MPEG-TS that contains data + + - .. row 3 + + - ifnum + + - number of the DVB interface. + + - .. row 4 + + - feedtype + + - Encapsulation type of the feed. It can be: + ``DVB_NET_FEEDTYPE_MPE`` for MPE encoding or + ``DVB_NET_FEEDTYPE_ULE`` for ULE encoding. + + + +.. _NET_REMOVE_IF: + +******************* +ioctl NET_REMOVE_IF +******************* + +*man NET_REMOVE_IF(2)* + +Removes a network interface. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, int ifnum ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_TONE + +``net_if`` + number of the interface to be removed + + +Description +=========== + +The NET_REMOVE_IF ioctl deletes an interface previously created via +:ref:`NET_ADD_IF `. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _NET_GET_IF: + +**************** +ioctl NET_GET_IF +**************** + +*man NET_GET_IF(2)* + +Read the configuration data of an interface created via +:ref:`NET_ADD_IF `. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, int request, struct dvb_net_if *net_if ) + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``request`` + FE_SET_TONE + +``net_if`` + pointer to struct :ref:`dvb_net_if ` + + +Description +=========== + +The NET_GET_IF ioctl uses the interface number given by the struct +:ref:`dvb_net_if `::ifnum field and fills the content of +struct :ref:`dvb_net_if ` with the packet ID and +encapsulation type used on such interface. If the interface was not +created yet with :ref:`NET_ADD_IF `, it will return -1 and fill +the ``errno`` with ``EINVAL`` error code. + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/net_h.rst b/Documentation/linux_tv/media/dvb/net_h.rst new file mode 100644 index 000000000000..357713b4a5ef --- /dev/null +++ b/Documentation/linux_tv/media/dvb/net_h.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _net_h: + +*********************** +DVB Network Header File +*********************** + + +.. toctree:: + :maxdepth: 1 + + ../../net.h + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/query-dvb-frontend-info.rst b/Documentation/linux_tv/media/dvb/query-dvb-frontend-info.rst new file mode 100644 index 000000000000..4a4fd5af6e0f --- /dev/null +++ b/Documentation/linux_tv/media/dvb/query-dvb-frontend-info.rst @@ -0,0 +1,22 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _query-dvb-frontend-info: + +***************************** +Querying frontend information +***************************** + +Usually, the first thing to do when the frontend is opened is to check +the frontend capabilities. This is done using +:ref:`FE_GET_INFO `. This ioctl will enumerate the +DVB API version and other characteristics about the frontend, and can be +opened either in read only or read/write mode. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/video.rst b/Documentation/linux_tv/media/dvb/video.rst new file mode 100644 index 000000000000..9783e9f344f6 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/video.rst @@ -0,0 +1,46 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dvb_video: + +################ +DVB Video Device +################ +The DVB video device controls the MPEG2 video decoder of the DVB +hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data +types and and ioctl definitions can be accessed by including +**linux/dvb/video.h** in your application. + +Note that the DVB video device only controls decoding of the MPEG video +stream, not its presentation on the TV or computer screen. On PCs this +is typically handled by an associated video4linux device, e.g. +**/dev/video**, which allows scaling and defining output windows. + +Some DVB cards don’t have their own MPEG decoder, which results in the +omission of the audio and video device as well as the video4linux +device. + +The ioctls that deal with SPUs (sub picture units) and navigation +packets are only supported on some MPEG decoders made for DVD playback. + +These ioctls were also used by V4L2 to control MPEG decoders implemented +in V4L2. The use of these ioctls for that purpose has been made obsolete +and proper V4L2 ioctls or controls have been created to replace that +functionality. + + +.. toctree:: + :maxdepth: 1 + + video_types + video_function_calls + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/video_function_calls.rst b/Documentation/linux_tv/media/dvb/video_function_calls.rst new file mode 100644 index 000000000000..3add2b85450d --- /dev/null +++ b/Documentation/linux_tv/media/dvb/video_function_calls.rst @@ -0,0 +1,1880 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _video_function_calls: + +******************** +Video Function Calls +******************** + + +.. _video_fopen: + +open() +====== + +DESCRIPTION + +This system call opens a named video device (e.g. +/dev/dvb/adapter0/video0) for subsequent use. + +When an open() call has succeeded, the device will be ready for use. The +significance of blocking or non-blocking mode is described in the +documentation for functions where there is a difference. It does not +affect the semantics of the open() call itself. A device opened in +blocking mode can later be put into non-blocking mode (and vice versa) +using the F_SETFL command of the fcntl system call. This is a standard +system call, documented in the Linux manual page for fcntl. Only one +user can open the Video Device in O_RDWR mode. All other attempts to +open the device in this mode will fail, and an error-code will be +returned. If the Video Device is opened in O_RDONLY mode, the only +ioctl call that can be used is VIDEO_GET_STATUS. All other call will +return an error code. + +SYNOPSIS + +int open(const char *deviceName, int flags); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - const char *deviceName + + - Name of specific video device. + + - .. row 2 + + - int flags + + - A bit-wise OR of the following flags: + + - .. row 3 + + - + - O_RDONLY read-only access + + - .. row 4 + + - + - O_RDWR read/write access + + - .. row 5 + + - + - O_NONBLOCK open in non-blocking mode + + - .. row 6 + + - + - (blocking mode is the default) + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - ENODEV + + - Device driver not loaded/available. + + - .. row 2 + + - EINTERNAL + + - Internal error. + + - .. row 3 + + - EBUSY + + - Device or resource busy. + + - .. row 4 + + - EINVAL + + - Invalid argument. + + + +.. _video_fclose: + +close() +======= + +DESCRIPTION + +This system call closes a previously opened video device. + +SYNOPSIS + +int close(int fd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _video_fwrite: + +write() +======= + +DESCRIPTION + +This system call can only be used if VIDEO_SOURCE_MEMORY is selected +in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in +PES format, unless the capability allows other formats. If O_NONBLOCK +is not specified the function will block until buffer space is +available. The amount of data to be transferred is implied by count. + +SYNOPSIS + +size_t write(int fd, const void *buf, size_t count); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - void *buf + + - Pointer to the buffer containing the PES data. + + - .. row 3 + + - size_t count + + - Size of buf. + + +RETURN VALUE + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EPERM + + - Mode VIDEO_SOURCE_MEMORY not selected. + + - .. row 2 + + - ENOMEM + + - Attempted to write more data than the internal buffer can hold. + + - .. row 3 + + - EBADF + + - fd is not a valid open file descriptor. + + + +.. _VIDEO_STOP: + +VIDEO_STOP +========== + +DESCRIPTION + +This ioctl is for DVB devices only. To control a V4L2 decoder use the +V4L2 :ref:`VIDIOC_DECODER_CMD ` instead. + +This ioctl call asks the Video Device to stop playing the current +stream. Depending on the input parameter, the screen can be blanked out +or displaying the last decoded frame. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_STOP, boolean mode); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_STOP for this command. + + - .. row 3 + + - Boolean mode + + - Indicates how the screen shall be handled. + + - .. row 4 + + - + - TRUE: Blank screen when stop. + + - .. row 5 + + - + - FALSE: Show last decoded frame. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_PLAY: + +VIDEO_PLAY +========== + +DESCRIPTION + +This ioctl is for DVB devices only. To control a V4L2 decoder use the +V4L2 :ref:`VIDIOC_DECODER_CMD ` instead. + +This ioctl call asks the Video Device to start playing a video stream +from the selected source. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_PLAY); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_PLAY for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_FREEZE: + +VIDEO_FREEZE +============ + +DESCRIPTION + +This ioctl is for DVB devices only. To control a V4L2 decoder use the +V4L2 :ref:`VIDIOC_DECODER_CMD ` instead. + +This ioctl call suspends the live video stream being played. Decoding +and playing are frozen. It is then possible to restart the decoding and +playing process of the video stream using the VIDEO_CONTINUE command. +If VIDEO_SOURCE_MEMORY is selected in the ioctl call +VIDEO_SELECT_SOURCE, the DVB subsystem will not decode any more data +until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_FREEZE); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_FREEZE for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_CONTINUE: + +VIDEO_CONTINUE +============== + +DESCRIPTION + +This ioctl is for DVB devices only. To control a V4L2 decoder use the +V4L2 :ref:`VIDIOC_DECODER_CMD ` instead. + +This ioctl call restarts decoding and playing processes of the video +stream which was played before a call to VIDEO_FREEZE was made. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_CONTINUE); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_CONTINUE for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SELECT_SOURCE: + +VIDEO_SELECT_SOURCE +=================== + +DESCRIPTION + +This ioctl is for DVB devices only. This ioctl was also supported by the +V4L2 ivtv driver, but that has been replaced by the ivtv-specific +``IVTV_IOC_PASSTHROUGH_MODE`` ioctl. + +This ioctl call informs the video device which source shall be used for +the input data. The possible sources are demux or memory. If memory is +selected, the data is fed to the video device through the write command. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SELECT_SOURCE, +video_stream_source_t source); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SELECT_SOURCE for this command. + + - .. row 3 + + - video_stream_source_t source + + - Indicates which source shall be used for the Video stream. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SET_BLANK: + +VIDEO_SET_BLANK +=============== + +DESCRIPTION + +This ioctl call asks the Video Device to blank out the picture. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_BLANK, boolean mode); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_BLANK for this command. + + - .. row 3 + + - boolean mode + + - TRUE: Blank screen when stop. + + - .. row 4 + + - + - FALSE: Show last decoded frame. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_GET_STATUS: + +VIDEO_GET_STATUS +================ + +DESCRIPTION + +This ioctl call asks the Video Device to return the current status of +the device. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_GET_STATUS, struct video_status +*status); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_STATUS for this command. + + - .. row 3 + + - struct video_status *status + + - Returns the current status of the Video Device. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_GET_FRAME_COUNT: + +VIDEO_GET_FRAME_COUNT +===================== + +DESCRIPTION + +This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders +this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_FRAME`` +control. + +This ioctl call asks the Video Device to return the number of displayed +frames since the decoder was started. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_GET_FRAME_COUNT, __u64 *pts); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_FRAME_COUNT for this command. + + - .. row 3 + + - __u64 *pts + + - Returns the number of frames displayed since the decoder was + started. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_GET_PTS: + +VIDEO_GET_PTS +============= + +DESCRIPTION + +This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders +this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_PTS`` +control. + +This ioctl call asks the Video Device to return the current PTS +timestamp. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_GET_PTS, __u64 *pts); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_PTS for this command. + + - .. row 3 + + - __u64 *pts + + - Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 / + ISO/IEC 13818-1. + + The PTS should belong to the currently played frame if possible, + but may also be a value close to it like the PTS of the last + decoded frame or the last PTS extracted by the PES parser. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_GET_FRAME_RATE: + +VIDEO_GET_FRAME_RATE +==================== + +DESCRIPTION + +This ioctl call asks the Video Device to return the current framerate. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_GET_FRAME_RATE, unsigned int +*rate); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_FRAME_RATE for this command. + + - .. row 3 + + - unsigned int *rate + + - Returns the framerate in number of frames per 1000 seconds. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_GET_EVENT: + +VIDEO_GET_EVENT +=============== + +DESCRIPTION + +This ioctl is for DVB devices only. To get events from a V4L2 decoder +use the V4L2 :ref:`VIDIOC_DQEVENT ` ioctl instead. + +This ioctl call returns an event of type video_event if available. If +an event is not available, the behavior depends on whether the device is +in blocking or non-blocking mode. In the latter case, the call fails +immediately with errno set to EWOULDBLOCK. In the former case, the call +blocks until an event becomes available. The standard Linux poll() +and/or select() system calls can be used with the device file descriptor +to watch for new events. For select(), the file descriptor should be +included in the exceptfds argument, and for poll(), POLLPRI should be +specified as the wake-up condition. Read-only permissions are sufficient +for this ioctl call. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_GET_EVENT, struct video_event *ev); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_EVENT for this command. + + - .. row 3 + + - struct video_event *ev + + - Points to the location where the event, if any, is to be stored. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EWOULDBLOCK + + - There is no event pending, and the device is in non-blocking mode. + + - .. row 2 + + - EOVERFLOW + + - Overflow in event queue - one or more events were lost. + + + +.. _VIDEO_COMMAND: + +VIDEO_COMMAND +============= + +DESCRIPTION + +This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders +this ioctl has been replaced by the +:ref:`VIDIOC_DECODER_CMD ` ioctl. + +This ioctl commands the decoder. The ``video_command`` struct is a +subset of the ``v4l2_decoder_cmd`` struct, so refer to the +:ref:`VIDIOC_DECODER_CMD ` documentation for +more information. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_COMMAND, struct video_command +*cmd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_COMMAND for this command. + + - .. row 3 + + - struct video_command *cmd + + - Commands the decoder. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_TRY_COMMAND: + +VIDEO_TRY_COMMAND +================= + +DESCRIPTION + +This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders +this ioctl has been replaced by the +:ref:`VIDIOC_TRY_DECODER_CMD ` ioctl. + +This ioctl tries a decoder command. The ``video_command`` struct is a +subset of the ``v4l2_decoder_cmd`` struct, so refer to the +:ref:`VIDIOC_TRY_DECODER_CMD ` documentation +for more information. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_TRY_COMMAND, struct +video_command *cmd); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_TRY_COMMAND for this command. + + - .. row 3 + + - struct video_command *cmd + + - Try a decoder command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_GET_SIZE: + +VIDEO_GET_SIZE +============== + +DESCRIPTION + +This ioctl returns the size and aspect ratio. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_GET_SIZE, video_size_t *size); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_SIZE for this command. + + - .. row 3 + + - video_size_t *size + + - Returns the size and aspect ratio. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SET_DISPLAY_FORMAT: + +VIDEO_SET_DISPLAY_FORMAT +======================== + +DESCRIPTION + +This ioctl call asks the Video Device to select the video format to be +applied by the MPEG chip on the video. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_DISPLAY_FORMAT, +video_display_format_t format); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_DISPLAY_FORMAT for this command. + + - .. row 3 + + - video_display_format_t format + + - Selects the video format to be used. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_STILLPICTURE: + +VIDEO_STILLPICTURE +================== + +DESCRIPTION + +This ioctl call asks the Video Device to display a still picture +(I-frame). The input data shall contain an I-frame. If the pointer is +NULL, then the current displayed still picture is blanked. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_STILLPICTURE, struct +video_still_picture *sp); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_STILLPICTURE for this command. + + - .. row 3 + + - struct video_still_picture *sp + + - Pointer to a location where an I-frame and size is stored. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_FAST_FORWARD: + +VIDEO_FAST_FORWARD +================== + +DESCRIPTION + +This ioctl call asks the Video Device to skip decoding of N number of +I-frames. This call can only be used if VIDEO_SOURCE_MEMORY is +selected. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_FAST_FORWARD, int nFrames); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_FAST_FORWARD for this command. + + - .. row 3 + + - int nFrames + + - The number of frames to skip. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EPERM + + - Mode VIDEO_SOURCE_MEMORY not selected. + + + +.. _VIDEO_SLOWMOTION: + +VIDEO_SLOWMOTION +================ + +DESCRIPTION + +This ioctl call asks the video device to repeat decoding frames N number +of times. This call can only be used if VIDEO_SOURCE_MEMORY is +selected. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SLOWMOTION, int nFrames); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SLOWMOTION for this command. + + - .. row 3 + + - int nFrames + + - The number of times to repeat each frame. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EPERM + + - Mode VIDEO_SOURCE_MEMORY not selected. + + + +.. _VIDEO_GET_CAPABILITIES: + +VIDEO_GET_CAPABILITIES +====================== + +DESCRIPTION + +This ioctl call asks the video device about its decoding capabilities. +On success it returns and integer which has bits set according to the +defines in section ??. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_GET_CAPABILITIES, unsigned int +*cap); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_CAPABILITIES for this command. + + - .. row 3 + + - unsigned int *cap + + - Pointer to a location where to store the capability information. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SET_ID: + +VIDEO_SET_ID +============ + +DESCRIPTION + +This ioctl selects which sub-stream is to be decoded if a program or +system stream is sent to the video device. + +SYNOPSIS + +int ioctl(int fd, int request = VIDEO_SET_ID, int id); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_ID for this command. + + - .. row 3 + + - int id + + - video sub-stream id + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - Invalid sub-stream id. + + + +.. _VIDEO_CLEAR_BUFFER: + +VIDEO_CLEAR_BUFFER +================== + +DESCRIPTION + +This ioctl call clears all video buffers in the driver and in the +decoder hardware. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_CLEAR_BUFFER); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_CLEAR_BUFFER for this command. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SET_STREAMTYPE: + +VIDEO_SET_STREAMTYPE +==================== + +DESCRIPTION + +This ioctl tells the driver which kind of stream to expect being written +to it. If this call is not used the default of video PES is used. Some +drivers might not support this call and always expect PES. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_STREAMTYPE, int type); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_STREAMTYPE for this command. + + - .. row 3 + + - int type + + - stream type + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SET_FORMAT: + +VIDEO_SET_FORMAT +================ + +DESCRIPTION + +This ioctl sets the screen format (aspect ratio) of the connected output +device (TV) so that the output of the decoder can be adjusted +accordingly. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_FORMAT, video_format_t +format); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_FORMAT for this command. + + - .. row 3 + + - video_format_t format + + - video format of TV as defined in section ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - format is not a valid video format. + + + +.. _VIDEO_SET_SYSTEM: + +VIDEO_SET_SYSTEM +================ + +DESCRIPTION + +This ioctl sets the television output format. The format (see section +??) may vary from the color format of the displayed MPEG stream. If the +hardware is not able to display the requested format the call will +return an error. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_SYSTEM , video_system_t +system); + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_FORMAT for this command. + + - .. row 3 + + - video_system_t system + + - video system of TV output. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - system is not a valid or supported video system. + + + +.. _VIDEO_SET_HIGHLIGHT: + +VIDEO_SET_HIGHLIGHT +=================== + +DESCRIPTION + +This ioctl sets the SPU highlight information for the menu access of a +DVD. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_HIGHLIGHT ,video_highlight_t +*vhilite) + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_HIGHLIGHT for this command. + + - .. row 3 + + - video_highlight_t *vhilite + + - SPU Highlight information according to section ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + +.. _VIDEO_SET_SPU: + +VIDEO_SET_SPU +============= + +DESCRIPTION + +This ioctl activates or deactivates SPU decoding in a DVD input stream. +It can only be used, if the driver is able to handle a DVD stream. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_SPU , video_spu_t *spu) + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_SPU for this command. + + - .. row 3 + + - video_spu_t *spu + + - SPU decoding (de)activation and subid setting according to section + ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - input is not a valid spu setting or driver cannot handle SPU. + + + +.. _VIDEO_SET_SPU_PALETTE: + +VIDEO_SET_SPU_PALETTE +===================== + +DESCRIPTION + +This ioctl sets the SPU color palette. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_SPU_PALETTE +,video_spu_palette_t *palette ) + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_SPU_PALETTE for this command. + + - .. row 3 + + - video_spu_palette_t *palette + + - SPU palette according to section ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - input is not a valid palette or driver doesn’t handle SPU. + + + +.. _VIDEO_GET_NAVI: + +VIDEO_GET_NAVI +============== + +DESCRIPTION + +This ioctl returns navigational information from the DVD stream. This is +especially needed if an encoded stream has to be decoded by the +hardware. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_GET_NAVI , video_navi_pack_t +*navipack) + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_GET_NAVI for this command. + + - .. row 3 + + - video_navi_pack_t *navipack + + - PCI or DSI pack (private stream 2) according to section ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EFAULT + + - driver is not able to return navigational information + + + +.. _VIDEO_SET_ATTRIBUTES: + +VIDEO_SET_ATTRIBUTES +==================== + +DESCRIPTION + +This ioctl is intended for DVD playback and allows you to set certain +information about the stream. Some hardware may not need this +information, but the call also tells the hardware to prepare for DVD +playback. + +SYNOPSIS + +int ioctl(fd, int request = VIDEO_SET_ATTRIBUTE ,video_attributes_t +vattr) + +PARAMETERS + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - int fd + + - File descriptor returned by a previous call to open(). + + - .. row 2 + + - int request + + - Equals VIDEO_SET_ATTRIBUTE for this command. + + - .. row 3 + + - video_attributes_t vattr + + - video attributes according to section ??. + + +RETURN VALUE + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - EINVAL + + - input is not a valid attribute setting. + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/video_h.rst b/Documentation/linux_tv/media/dvb/video_h.rst new file mode 100644 index 000000000000..348d20c3cab7 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/video_h.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _video_h: + +********************* +DVB Video Header File +********************* + + +.. toctree:: + :maxdepth: 1 + + ../../video.h + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/dvb/video_types.rst b/Documentation/linux_tv/media/dvb/video_types.rst new file mode 100644 index 000000000000..f57233825e42 --- /dev/null +++ b/Documentation/linux_tv/media/dvb/video_types.rst @@ -0,0 +1,390 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _video_types: + +**************** +Video Data Types +**************** + + +.. _video-format-t: + +video_format_t +============== + +The ``video_format_t`` data type defined by + + +.. code-block:: c + + typedef enum { + VIDEO_FORMAT_4_3, /* Select 4:3 format */ + VIDEO_FORMAT_16_9, /* Select 16:9 format. */ + VIDEO_FORMAT_221_1 /* 2.21:1 */ + } video_format_t; + +is used in the VIDEO_SET_FORMAT function (??) to tell the driver which +aspect ratio the output hardware (e.g. TV) has. It is also used in the +data structures video_status (??) returned by VIDEO_GET_STATUS (??) +and video_event (??) returned by VIDEO_GET_EVENT (??) which report +about the display format of the current video stream. + + +.. _video-displayformat-t: + +video_displayformat_t +===================== + +In case the display format of the video stream and of the display +hardware differ the application has to specify how to handle the +cropping of the picture. This can be done using the +VIDEO_SET_DISPLAY_FORMAT call (??) which accepts + + +.. code-block:: c + + typedef enum { + VIDEO_PAN_SCAN, /* use pan and scan format */ + VIDEO_LETTER_BOX, /* use letterbox format */ + VIDEO_CENTER_CUT_OUT /* use center cut out format */ + } video_displayformat_t; + +as argument. + + +.. _video-stream-source-t: + +video_stream_source_t +===================== + +The video stream source is set through the VIDEO_SELECT_SOURCE call +and can take the following values, depending on whether we are replaying +from an internal (demuxer) or external (user write) source. + + +.. code-block:: c + + typedef enum { + VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ + VIDEO_SOURCE_MEMORY /* If this source is selected, the stream + comes from the user through the write + system call */ + } video_stream_source_t; + +VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the +frontend or the DVR device) as the source of the video stream. If +VIDEO_SOURCE_MEMORY is selected the stream comes from the application +through the **write()** system call. + + +.. _video-play-state-t: + +video_play_state_t +================== + +The following values can be returned by the VIDEO_GET_STATUS call +representing the state of video playback. + + +.. code-block:: c + + typedef enum { + VIDEO_STOPPED, /* Video is stopped */ + VIDEO_PLAYING, /* Video is currently playing */ + VIDEO_FREEZED /* Video is freezed */ + } video_play_state_t; + + +.. _video-command: + +struct video_command +==================== + +The structure must be zeroed before use by the application This ensures +it can be extended safely in the future. + + +.. code-block:: c + + struct video_command { + __u32 cmd; + __u32 flags; + union { + struct { + __u64 pts; + } stop; + + struct { + /* 0 or 1000 specifies normal speed, + 1 specifies forward single stepping, + -1 specifies backward single stepping, + >>1: playback at speed/1000 of the normal speed, + <-1: reverse playback at (-speed/1000) of the normal speed. */ + __s32 speed; + __u32 format; + } play; + + struct { + __u32 data[16]; + } raw; + }; + }; + + +.. _video-size-t: + +video_size_t +============ + + +.. code-block:: c + + typedef struct { + int w; + int h; + video_format_t aspect_ratio; + } video_size_t; + + +.. _video-event: + +struct video_event +================== + +The following is the structure of a video event as it is returned by the +VIDEO_GET_EVENT call. + + +.. code-block:: c + + struct video_event { + __s32 type; + #define VIDEO_EVENT_SIZE_CHANGED 1 + #define VIDEO_EVENT_FRAME_RATE_CHANGED 2 + #define VIDEO_EVENT_DECODER_STOPPED 3 + #define VIDEO_EVENT_VSYNC 4 + __kernel_time_t timestamp; + union { + video_size_t size; + unsigned int frame_rate; /* in frames per 1000sec */ + unsigned char vsync_field; /* unknown/odd/even/progressive */ + } u; + }; + + +.. _video-status: + +struct video_status +=================== + +The VIDEO_GET_STATUS call returns the following structure informing +about various states of the playback operation. + + +.. code-block:: c + + struct video_status { + int video_blank; /* blank video on freeze? */ + video_play_state_t play_state; /* current state of playback */ + video_stream_source_t stream_source; /* current source (demux/memory) */ + video_format_t video_format; /* current aspect ratio of stream */ + video_displayformat_t display_format;/* selected cropping mode */ + }; + +If video_blank is set video will be blanked out if the channel is +changed or if playback is stopped. Otherwise, the last picture will be +displayed. play_state indicates if the video is currently frozen, +stopped, or being played back. The stream_source corresponds to the +seleted source for the video stream. It can come either from the +demultiplexer or from memory. The video_format indicates the aspect +ratio (one of 4:3 or 16:9) of the currently played video stream. +Finally, display_format corresponds to the selected cropping mode in +case the source video format is not the same as the format of the output +device. + + +.. _video-still-picture: + +struct video_still_picture +========================== + +An I-frame displayed via the VIDEO_STILLPICTURE call is passed on +within the following structure. + + +.. code-block:: c + + /* pointer to and size of a single iframe in memory */ + struct video_still_picture { + char *iFrame; /* pointer to a single iframe in memory */ + int32_t size; + }; + + +.. _video_caps: + +video capabilities +================== + +A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the +following bits set according to the hardwares capabilities. + + +.. code-block:: c + + /* bit definitions for capabilities: */ + /* can the hardware decode MPEG1 and/or MPEG2? */ + #define VIDEO_CAP_MPEG1 1 + #define VIDEO_CAP_MPEG2 2 + /* can you send a system and/or program stream to video device? + (you still have to open the video and the audio device but only + send the stream to the video device) */ + #define VIDEO_CAP_SYS 4 + #define VIDEO_CAP_PROG 8 + /* can the driver also handle SPU, NAVI and CSS encoded data? + (CSS API is not present yet) */ + #define VIDEO_CAP_SPU 16 + #define VIDEO_CAP_NAVI 32 + #define VIDEO_CAP_CSS 64 + + +.. _video-system: + +video_system_t +============== + +A call to VIDEO_SET_SYSTEM sets the desired video system for TV +output. The following system types can be set: + + +.. code-block:: c + + typedef enum { + VIDEO_SYSTEM_PAL, + VIDEO_SYSTEM_NTSC, + VIDEO_SYSTEM_PALN, + VIDEO_SYSTEM_PALNc, + VIDEO_SYSTEM_PALM, + VIDEO_SYSTEM_NTSC60, + VIDEO_SYSTEM_PAL60, + VIDEO_SYSTEM_PALM60 + } video_system_t; + + +.. _video-highlight: + +struct video_highlight +====================== + +Calling the ioctl VIDEO_SET_HIGHLIGHTS posts the SPU highlight +information. The call expects the following format for that information: + + +.. code-block:: c + + typedef + struct video_highlight { + boolean active; /* 1=show highlight, 0=hide highlight */ + uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ + /* 3- 0 Background pixel contrast */ + uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */ + /* 3- 0 Emphasis pixel-1 contrast */ + uint8_t color1; /* 7- 4 Pattern pixel color */ + /* 3- 0 Background pixel color */ + uint8_t color2; /* 7- 4 Emphasis pixel-2 color */ + /* 3- 0 Emphasis pixel-1 color */ + uint32_t ypos; /* 23-22 auto action mode */ + /* 21-12 start y */ + /* 9- 0 end y */ + uint32_t xpos; /* 23-22 button color number */ + /* 21-12 start x */ + /* 9- 0 end x */ + } video_highlight_t; + + +.. _video-spu: + +struct video_spu +================ + +Calling VIDEO_SET_SPU deactivates or activates SPU decoding, according +to the following format: + + +.. code-block:: c + + typedef + struct video_spu { + boolean active; + int stream_id; + } video_spu_t; + + +.. _video-spu-palette: + +struct video_spu_palette +======================== + +The following structure is used to set the SPU palette by calling +VIDEO_SPU_PALETTE: + + +.. code-block:: c + + typedef + struct video_spu_palette { + int length; + uint8_t *palette; + } video_spu_palette_t; + + +.. _video-navi-pack: + +struct video_navi_pack +====================== + +In order to get the navigational data the following structure has to be +passed to the ioctl VIDEO_GET_NAVI: + + +.. code-block:: c + + typedef + struct video_navi_pack { + int length; /* 0 ... 1024 */ + uint8_t data[1024]; + } video_navi_pack_t; + + +.. _video-attributes-t: + +video_attributes_t +================== + +The following attributes can be set by a call to VIDEO_SET_ATTRIBUTES: + + +.. code-block:: c + + typedef uint16_t video_attributes_t; + /* bits: descr. */ + /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ + /* 13-12 TV system (0=525/60, 1=625/50) */ + /* 11-10 Aspect ratio (0=4:3, 3=16:9) */ + /* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ + /* 7 line 21-1 data present in GOP (1=yes, 0=no) */ + /* 6 line 21-2 data present in GOP (1=yes, 0=no) */ + /* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ + /* 2 source letterboxed (1=yes, 0=no) */ + /* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/Remote_controllers_Intro.rst b/Documentation/linux_tv/media/v4l/Remote_controllers_Intro.rst new file mode 100644 index 000000000000..5e461ac39947 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/Remote_controllers_Intro.rst @@ -0,0 +1,33 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _Remote_controllers_Intro: + +************ +Introduction +************ + +Currently, most analog and digital devices have a Infrared input for +remote controllers. Each manufacturer has their own type of control. It +is not rare for the same manufacturer to ship different types of +controls, depending on the device. + +A Remote Controller interface is mapped as a normal evdev/input +interface, just like a keyboard or a mouse. So, it uses all ioctls +already defined for any other input devices. + +However, remove controllers are more flexible than a normal input +device, as the IR receiver (and/or transmitter) can be used in +conjunction with a wide variety of different IR remotes. + +In order to allow flexibility, the Remote Controller subsystem allows +controlling the RC-specific attributes via +:ref:`the sysfs class nodes `. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/Remote_controllers_table_change.rst b/Documentation/linux_tv/media/v4l/Remote_controllers_table_change.rst new file mode 100644 index 000000000000..a04cc2cbbbb3 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/Remote_controllers_table_change.rst @@ -0,0 +1,29 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _Remote_controllers_table_change: + +******************************************* +Changing default Remote Controller mappings +******************************************* + +The event interface provides two ioctls to be used against the +/dev/input/event device, to allow changing the default keymapping. + +This program demonstrates how to replace the keymap tables. + + +.. toctree:: + :maxdepth: 1 + + keytable.c + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/Remote_controllers_tables.rst b/Documentation/linux_tv/media/v4l/Remote_controllers_tables.rst new file mode 100644 index 000000000000..2243d5b2dcd1 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/Remote_controllers_tables.rst @@ -0,0 +1,768 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _Remote_controllers_tables: + +************************ +Remote controller tables +************************ + +Unfortunately, for several years, there was no effort to create uniform +IR keycodes for different devices. This caused the same IR keyname to be +mapped completely differently on different IR devices. This resulted +that the same IR keyname to be mapped completely different on different +IR's. Due to that, V4L2 API now specifies a standard for mapping Media +keys on IR. + +This standard should be used by both V4L/DVB drivers and userspace +applications + +The modules register the remote as keyboard within the linux input +layer. This means that the IR key strokes will look like normal keyboard +key strokes (if CONFIG_INPUT_KEYBOARD is enabled). Using the event +devices (CONFIG_INPUT_EVDEV) it is possible for applications to access +the remote via /dev/input/event devices. + + +.. _rc_standard_keymap: + +.. flat-table:: IR default keymapping + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + + - .. row 1 + + - Key code + + - Meaning + + - Key examples on IR + + - .. row 2 + + - **Numeric keys** + + - .. row 3 + + - ``KEY_0`` + + - Keyboard digit 0 + + - 0 + + - .. row 4 + + - ``KEY_1`` + + - Keyboard digit 1 + + - 1 + + - .. row 5 + + - ``KEY_2`` + + - Keyboard digit 2 + + - 2 + + - .. row 6 + + - ``KEY_3`` + + - Keyboard digit 3 + + - 3 + + - .. row 7 + + - ``KEY_4`` + + - Keyboard digit 4 + + - 4 + + - .. row 8 + + - ``KEY_5`` + + - Keyboard digit 5 + + - 5 + + - .. row 9 + + - ``KEY_6`` + + - Keyboard digit 6 + + - 6 + + - .. row 10 + + - ``KEY_7`` + + - Keyboard digit 7 + + - 7 + + - .. row 11 + + - ``KEY_8`` + + - Keyboard digit 8 + + - 8 + + - .. row 12 + + - ``KEY_9`` + + - Keyboard digit 9 + + - 9 + + - .. row 13 + + - **Movie play control** + + - .. row 14 + + - ``KEY_FORWARD`` + + - Instantly advance in time + + - >> / FORWARD + + - .. row 15 + + - ``KEY_BACK`` + + - Instantly go back in time + + - <<< / BACK + + - .. row 16 + + - ``KEY_FASTFORWARD`` + + - Play movie faster + + - >>> / FORWARD + + - .. row 17 + + - ``KEY_REWIND`` + + - Play movie back + + - REWIND / BACKWARD + + - .. row 18 + + - ``KEY_NEXT`` + + - Select next chapter / sub-chapter / interval + + - NEXT / SKIP + + - .. row 19 + + - ``KEY_PREVIOUS`` + + - Select previous chapter / sub-chapter / interval + + - << / PREV / PREVIOUS + + - .. row 20 + + - ``KEY_AGAIN`` + + - Repeat the video or a video interval + + - REPEAT / LOOP / RECALL + + - .. row 21 + + - ``KEY_PAUSE`` + + - Pause sroweam + + - PAUSE / FREEZE + + - .. row 22 + + - ``KEY_PLAY`` + + - Play movie at the normal timeshift + + - NORMAL TIMESHIFT / LIVE / > + + - .. row 23 + + - ``KEY_PLAYPAUSE`` + + - Alternate between play and pause + + - PLAY / PAUSE + + - .. row 24 + + - ``KEY_STOP`` + + - Stop sroweam + + - STOP + + - .. row 25 + + - ``KEY_RECORD`` + + - Start/stop recording sroweam + + - CAPTURE / REC / RECORD/PAUSE + + - .. row 26 + + - ``KEY_CAMERA`` + + - Take a picture of the image + + - CAMERA ICON / CAPTURE / SNAPSHOT + + - .. row 27 + + - ``KEY_SHUFFLE`` + + - Enable shuffle mode + + - SHUFFLE + + - .. row 28 + + - ``KEY_TIME`` + + - Activate time shift mode + + - TIME SHIFT + + - .. row 29 + + - ``KEY_TITLE`` + + - Allow changing the chapter + + - CHAPTER + + - .. row 30 + + - ``KEY_SUBTITLE`` + + - Allow changing the subtitle + + - SUBTITLE + + - .. row 31 + + - **Image control** + + - .. row 32 + + - ``KEY_BRIGHTNESSDOWN`` + + - Decrease Brightness + + - BRIGHTNESS DECREASE + + - .. row 33 + + - ``KEY_BRIGHTNESSUP`` + + - Increase Brightness + + - BRIGHTNESS INCREASE + + - .. row 34 + + - ``KEY_ANGLE`` + + - Switch video camera angle (on videos with more than one angle + stored) + + - ANGLE / SWAP + + - .. row 35 + + - ``KEY_EPG`` + + - Open the Elecrowonic Play Guide (EPG) + + - EPG / GUIDE + + - .. row 36 + + - ``KEY_TEXT`` + + - Activate/change closed caption mode + + - CLOSED CAPTION/TELETEXT / DVD TEXT / TELETEXT / TTX + + - .. row 37 + + - **Audio control** + + - .. row 38 + + - ``KEY_AUDIO`` + + - Change audio source + + - AUDIO SOURCE / AUDIO / MUSIC + + - .. row 39 + + - ``KEY_MUTE`` + + - Mute/unmute audio + + - MUTE / DEMUTE / UNMUTE + + - .. row 40 + + - ``KEY_VOLUMEDOWN`` + + - Decrease volume + + - VOLUME- / VOLUME DOWN + + - .. row 41 + + - ``KEY_VOLUMEUP`` + + - Increase volume + + - VOLUME+ / VOLUME UP + + - .. row 42 + + - ``KEY_MODE`` + + - Change sound mode + + - MONO/STEREO + + - .. row 43 + + - ``KEY_LANGUAGE`` + + - Select Language + + - 1ST / 2ND LANGUAGE / DVD LANG / MTS/SAP / MTS SEL + + - .. row 44 + + - **Channel control** + + - .. row 45 + + - ``KEY_CHANNEL`` + + - Go to the next favorite channel + + - ALT / CHANNEL / CH SURFING / SURF / FAV + + - .. row 46 + + - ``KEY_CHANNELDOWN`` + + - Decrease channel sequencially + + - CHANNEL - / CHANNEL DOWN / DOWN + + - .. row 47 + + - ``KEY_CHANNELUP`` + + - Increase channel sequencially + + - CHANNEL + / CHANNEL UP / UP + + - .. row 48 + + - ``KEY_DIGITS`` + + - Use more than one digit for channel + + - PLUS / 100/ 1xx / xxx / -/-- / Single Double Triple Digit + + - .. row 49 + + - ``KEY_SEARCH`` + + - Start channel autoscan + + - SCAN / AUTOSCAN + + - .. row 50 + + - **Colored keys** + + - .. row 51 + + - ``KEY_BLUE`` + + - IR Blue key + + - BLUE + + - .. row 52 + + - ``KEY_GREEN`` + + - IR Green Key + + - GREEN + + - .. row 53 + + - ``KEY_RED`` + + - IR Red key + + - RED + + - .. row 54 + + - ``KEY_YELLOW`` + + - IR Yellow key + + - YELLOW + + - .. row 55 + + - **Media selection** + + - .. row 56 + + - ``KEY_CD`` + + - Change input source to Compact Disc + + - CD + + - .. row 57 + + - ``KEY_DVD`` + + - Change input to DVD + + - DVD / DVD MENU + + - .. row 58 + + - ``KEY_EJECTCLOSECD`` + + - Open/close the CD/DVD player + + - -> ) / CLOSE / OPEN + + - .. row 59 + + - ``KEY_MEDIA`` + + - Turn on/off Media application + + - PC/TV / TURN ON/OFF APP + + - .. row 60 + + - ``KEY_PC`` + + - Selects from TV to PC + + - PC + + - .. row 61 + + - ``KEY_RADIO`` + + - Put into AM/FM radio mode + + - RADIO / TV/FM / TV/RADIO / FM / FM/RADIO + + - .. row 62 + + - ``KEY_TV`` + + - Select tv mode + + - TV / LIVE TV + + - .. row 63 + + - ``KEY_TV2`` + + - Select Cable mode + + - AIR/CBL + + - .. row 64 + + - ``KEY_VCR`` + + - Select VCR mode + + - VCR MODE / DTR + + - .. row 65 + + - ``KEY_VIDEO`` + + - Alternate between input modes + + - SOURCE / SELECT / DISPLAY / SWITCH INPUTS / VIDEO + + - .. row 66 + + - **Power control** + + - .. row 67 + + - ``KEY_POWER`` + + - Turn on/off computer + + - SYSTEM POWER / COMPUTER POWER + + - .. row 68 + + - ``KEY_POWER2`` + + - Turn on/off application + + - TV ON/OFF / POWER + + - .. row 69 + + - ``KEY_SLEEP`` + + - Activate sleep timer + + - SLEEP / SLEEP TIMER + + - .. row 70 + + - ``KEY_SUSPEND`` + + - Put computer into suspend mode + + - STANDBY / SUSPEND + + - .. row 71 + + - **Window control** + + - .. row 72 + + - ``KEY_CLEAR`` + + - Stop sroweam and return to default input video/audio + + - CLEAR / RESET / BOSS KEY + + - .. row 73 + + - ``KEY_CYCLEWINDOWS`` + + - Minimize windows and move to the next one + + - ALT-TAB / MINIMIZE / DESKTOP + + - .. row 74 + + - ``KEY_FAVORITES`` + + - Open the favorites sroweam window + + - TV WALL / Favorites + + - .. row 75 + + - ``KEY_MENU`` + + - Call application menu + + - 2ND CONTROLS (USA: MENU) / DVD/MENU / SHOW/HIDE CTRL + + - .. row 76 + + - ``KEY_NEW`` + + - Open/Close Picture in Picture + + - PIP + + - .. row 77 + + - ``KEY_OK`` + + - Send a confirmation code to application + + - OK / ENTER / RETURN + + - .. row 78 + + - ``KEY_SCREEN`` + + - Select screen aspect ratio + + - 4:3 16:9 SELECT + + - .. row 79 + + - ``KEY_ZOOM`` + + - Put device into zoom/full screen mode + + - ZOOM / FULL SCREEN / ZOOM+ / HIDE PANNEL / SWITCH + + - .. row 80 + + - **Navigation keys** + + - .. row 81 + + - ``KEY_ESC`` + + - Cancel current operation + + - CANCEL / BACK + + - .. row 82 + + - ``KEY_HELP`` + + - Open a Help window + + - HELP + + - .. row 83 + + - ``KEY_HOMEPAGE`` + + - Navigate to Homepage + + - HOME + + - .. row 84 + + - ``KEY_INFO`` + + - Open On Screen Display + + - DISPLAY INFORMATION / OSD + + - .. row 85 + + - ``KEY_WWW`` + + - Open the default browser + + - WEB + + - .. row 86 + + - ``KEY_UP`` + + - Up key + + - UP + + - .. row 87 + + - ``KEY_DOWN`` + + - Down key + + - DOWN + + - .. row 88 + + - ``KEY_LEFT`` + + - Left key + + - LEFT + + - .. row 89 + + - ``KEY_RIGHT`` + + - Right key + + - RIGHT + + - .. row 90 + + - **Miscellaneous keys** + + - .. row 91 + + - ``KEY_DOT`` + + - Return a dot + + - . + + - .. row 92 + + - ``KEY_FN`` + + - Select a function + + - FUNCTION + + +It should be noted that, sometimes, there some fundamental missing keys +at some cheaper IR's. Due to that, it is recommended to: + + +.. _rc_keymap_notes: + +.. flat-table:: Notes + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - On simpler IR's, without separate channel keys, you need to map UP + as ``KEY_CHANNELUP`` + + - .. row 2 + + - On simpler IR's, without separate channel keys, you need to map + DOWN as ``KEY_CHANNELDOWN`` + + - .. row 3 + + - On simpler IR's, without separate volume keys, you need to map + LEFT as ``KEY_VOLUMEDOWN`` + + - .. row 4 + + - On simpler IR's, without separate volume keys, you need to map + RIGHT as ``KEY_VOLUMEUP`` + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/app-pri.rst b/Documentation/linux_tv/media/v4l/app-pri.rst new file mode 100644 index 000000000000..9716437ae14d --- /dev/null +++ b/Documentation/linux_tv/media/v4l/app-pri.rst @@ -0,0 +1,39 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _app-pri: + +******************** +Application Priority +******************** + +When multiple applications share a device it may be desirable to assign +them different priorities. Contrary to the traditional "rm -rf /" school +of thought a video recording application could for example block other +applications from changing video controls or switching the current TV +channel. Another objective is to permit low priority applications +working in background, which can be preempted by user controlled +applications and automatically regain control of the device at a later +time. + +Since these features cannot be implemented entirely in user space V4L2 +defines the :ref:`VIDIOC_G_PRIORITY ` and +:ref:`VIDIOC_S_PRIORITY ` ioctls to request and +query the access priority associate with a file descriptor. Opening a +device assigns a medium priority, compatible with earlier versions of +V4L2 and drivers not supporting these ioctls. Applications requiring a +different priority will usually call ``VIDIOC_S_PRIORITY`` after +verifying the device with the +:ref:`VIDIOC_QUERYCAP ` ioctl. + +Ioctls changing driver properties, such as +:ref:`VIDIOC_S_INPUT `, return an EBUSY error code +after another application obtained higher priority. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/async.rst b/Documentation/linux_tv/media/v4l/async.rst new file mode 100644 index 000000000000..82a56e88a54d --- /dev/null +++ b/Documentation/linux_tv/media/v4l/async.rst @@ -0,0 +1,18 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _async: + +**************** +Asynchronous I/O +**************** + +This method is not defined yet. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/audio.rst b/Documentation/linux_tv/media/v4l/audio.rst new file mode 100644 index 000000000000..5e37adfbb49c --- /dev/null +++ b/Documentation/linux_tv/media/v4l/audio.rst @@ -0,0 +1,97 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _audio: + +************************ +Audio Inputs and Outputs +************************ + +Audio inputs and outputs are physical connectors of a device. Video +capture devices have inputs, output devices have outputs, zero or more +each. Radio devices have no audio inputs or outputs. They have exactly +one tuner which in fact *is* an audio source, but this API associates +tuners with video inputs or outputs only, and radio devices have none of +these. [1]_ A connector on a TV card to loop back the received audio +signal to a sound card is not considered an audio output. + +Audio and video inputs and outputs are associated. Selecting a video +source also selects an audio source. This is most evident when the video +and audio source is a tuner. Further audio connectors can combine with +more than one video input or output. Assumed two composite video inputs +and two audio inputs exist, there may be up to four valid combinations. +The relation of video and audio connectors is defined in the +``audioset`` field of the respective struct +:ref:`v4l2_input ` or struct +:ref:`v4l2_output `, where each bit represents the index +number, starting at zero, of one audio input or output. + +To learn about the number and attributes of the available inputs and +outputs applications can enumerate them with the +:ref:`VIDIOC_ENUMAUDIO ` and +:ref:`VIDIOC_ENUMAUDOUT ` ioctl, respectively. +The struct :ref:`v4l2_audio ` returned by the +``VIDIOC_ENUMAUDIO`` ioctl also contains signal status information +applicable when the current audio input is queried. + +The :ref:`VIDIOC_G_AUDIO ` and +:ref:`VIDIOC_G_AUDOUT ` ioctls report the current +audio input and output, respectively. Note that, unlike +:ref:`VIDIOC_G_INPUT ` and +:ref:`VIDIOC_G_OUTPUT ` these ioctls return a +structure as ``VIDIOC_ENUMAUDIO`` and ``VIDIOC_ENUMAUDOUT`` do, not just +an index. + +To select an audio input and change its properties applications call the +:ref:`VIDIOC_S_AUDIO ` ioctl. To select an audio +output (which presently has no changeable properties) applications call +the :ref:`VIDIOC_S_AUDOUT ` ioctl. + +Drivers must implement all audio input ioctls when the device has +multiple selectable audio inputs, all audio output ioctls when the +device has multiple selectable audio outputs. When the device has any +audio inputs or outputs the driver must set the ``V4L2_CAP_AUDIO`` flag +in the struct :ref:`v4l2_capability ` returned by +the :ref:`VIDIOC_QUERYCAP ` ioctl. + + +.. code-block:: c + + struct v4l2_audio audio; + + memset(&audio, 0, sizeof(audio)); + + if (-1 == ioctl(fd, VIDIOC_G_AUDIO, &audio)) { + perror("VIDIOC_G_AUDIO"); + exit(EXIT_FAILURE); + } + + printf("Current input: %s\\n", audio.name); + + +.. code-block:: c + + struct v4l2_audio audio; + + memset(&audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */ + + audio.index = 0; + + if (-1 == ioctl(fd, VIDIOC_S_AUDIO, &audio)) { + perror("VIDIOC_S_AUDIO"); + exit(EXIT_FAILURE); + } + +.. [1] + Actually struct :ref:`v4l2_audio ` ought to have a + ``tuner`` field like struct :ref:`v4l2_input `, not + only making the API more consistent but also permitting radio devices + with multiple tuners. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/biblio.rst b/Documentation/linux_tv/media/v4l/biblio.rst new file mode 100644 index 000000000000..44dc7deb24b2 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/biblio.rst @@ -0,0 +1,390 @@ +.. -*- coding: utf-8; mode: rst -*- + +********** +References +********** + + +.. _cea608: + +CEA 608-E +========= + + +:title: CEA-608-E R-2014 "Line 21 Data Services" + +:author: Consumer Electronics Association (http://www.ce.org) + +.. _en300294: + +EN 300 294 +========== + + +:title: EN 300 294 "625-line television Wide Screen Signalling (WSS)" + +:author: European Telecommunication Standards Institute (http://www.etsi.org) + +.. _ets300231: + +ETS 300 231 +=========== + + +:title: ETS 300 231 "Specification of the domestic video Programme Delivery Control system (PDC)" + +:author: European Telecommunication Standards Institute (http://www.etsi.org) + +.. _ets300706: + +ETS 300 706 +=========== + + +:title: ETS 300 706 "Enhanced Teletext specification" + +:author: European Telecommunication Standards Institute (http://www.etsi.org) + +.. _mpeg2part1: + +ISO 13818-1 +=========== + + +:title: ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information technology — Generic coding of moving pictures and associated audio information: Systems" + +:author: International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch) + +.. _mpeg2part2: + +ISO 13818-2 +=========== + + +:title: ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information technology — Generic coding of moving pictures and associated audio information: Video" + +:author: International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch) + +.. _itu470: + +ITU BT.470 +========== + + +:title: ITU-R Recommendation BT.470-6 "Conventional Television Systems" + +:author: International Telecommunication Union (http://www.itu.ch) + +.. _itu601: + +ITU BT.601 +========== + + +:title: ITU-R Recommendation BT.601-5 "Studio Encoding Parameters of Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect Ratios" + +:author: International Telecommunication Union (http://www.itu.ch) + +.. _itu653: + +ITU BT.653 +========== + + +:title: ITU-R Recommendation BT.653-3 "Teletext systems" + +:author: International Telecommunication Union (http://www.itu.ch) + +.. _itu709: + +ITU BT.709 +========== + + +:title: ITU-R Recommendation BT.709-5 "Parameter values for the HDTV standards for production and international programme exchange" + +:author: International Telecommunication Union (http://www.itu.ch) + +.. _itu1119: + +ITU BT.1119 +=========== + + +:title: ITU-R Recommendation BT.1119 "625-line television Wide Screen Signalling (WSS)" + +:author: International Telecommunication Union (http://www.itu.ch) + +.. _jfif: + +JFIF +==== + + +:title: JPEG File Interchange Format +:subtitle: Version 1.02 + +:author: Independent JPEG Group (http://www.ijg.org) + +.. _itu-t81: + +ITU-T.81 +======== + + +:title: ITU-T Recommendation T.81 "Information Technology — Digital Compression and Coding of Continous-Tone Still Images — Requirements and Guidelines" + +:author: International Telecommunication Union (http://www.itu.int) + +.. _w3c-jpeg-jfif: + +W3C JPEG JFIF +============= + + +:title: JPEG JFIF + +:author: The World Wide Web Consortium (http://www.w3.org) + +.. _smpte12m: + +SMPTE 12M +========= + + +:title: SMPTE 12M-1999 "Television, Audio and Film - Time and Control Code" + +:author: Society of Motion Picture and Television Engineers (http://www.smpte.org) + +.. _smpte170m: + +SMPTE 170M +========== + + +:title: SMPTE 170M-1999 "Television - Composite Analog Video Signal - NTSC for Studio Applications" + +:author: Society of Motion Picture and Television Engineers (http://www.smpte.org) + +.. _smpte240m: + +SMPTE 240M +========== + + +:title: SMPTE 240M-1999 "Television - Signal Parameters - 1125-Line High-Definition Production" + +:author: Society of Motion Picture and Television Engineers (http://www.smpte.org) + +.. _smpte431: + +SMPTE RP 431-2 +============== + + +:title: SMPTE RP 431-2:2011 "D-Cinema Quality - Reference Projector and Environment" + +:author: Society of Motion Picture and Television Engineers (http://www.smpte.org) + +.. _smpte2084: + +SMPTE ST 2084 +============= + + +:title: SMPTE ST 2084:2014 "High Dynamic Range Electro-Optical Transfer Function of Master Reference Displays" + +:author: Society of Motion Picture and Television Engineers (http://www.smpte.org) + +.. _srgb: + +sRGB +==== + + +:title: IEC 61966-2-1 ed1.0 "Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB" + +:author: International Electrotechnical Commission (http://www.iec.ch) + +.. _sycc: + +sYCC +==== + + +:title: IEC 61966-2-1-am1 ed1.0 "Amendment 1 - Multimedia systems and equipment - Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB" + +:author: International Electrotechnical Commission (http://www.iec.ch) + +.. _xvycc: + +xvYCC +===== + + +:title: IEC 61966-2-4 ed1.0 "Multimedia systems and equipment - Colour measurement and management - Part 2-4: Colour management - Extended-gamut YCC colour space for video applications - xvYCC" + +:author: International Electrotechnical Commission (http://www.iec.ch) + +.. _adobergb: + +AdobeRGB +======== + + +:title: Adobe© RGB (1998) Color Image Encoding Version 2005-05 + +:author: Adobe Systems Incorporated (http://www.adobe.com) + +.. _oprgb: + +opRGB +===== + + +:title: IEC 61966-2-5 "Multimedia systems and equipment - Colour measurement and management - Part 2-5: Colour management - Optional RGB colour space - opRGB" + +:author: International Electrotechnical Commission (http://www.iec.ch) + +.. _itu2020: + +ITU BT.2020 +=========== + + +:title: ITU-R Recommendation BT.2020 (08/2012) "Parameter values for ultra-high definition television systems for production and international programme exchange" + +:author: International Telecommunication Union (http://www.itu.ch) + +.. _tech3213: + +EBU Tech 3213 +============= + + +:title: E.B.U. Standard for Chromaticity Tolerances for Studio Monitors" + +:author: European Broadcast Union (http://www.ebu.ch) + +.. _iec62106: + +IEC 62106 +========= + + +:title: Specification of the radio data system (RDS) for VHF/FM sound broadcasting in the frequency range from 87,5 to 108,0 MHz + +:author: International Electrotechnical Commission (http://www.iec.ch) + +.. _nrsc4: + +NRSC-4-B +======== + + +:title: NRSC-4-B: United States RBDS Standard + +:author: National Radio Systems Committee (http://www.nrscstandards.org) + +.. _iso12232: + +ISO 12232:2006 +============== + + +:title: Photography — Digital still cameras — Determination of exposure index, ISO speed ratings, standard output sensitivity, and recommended exposure index + +:author: International Organization for Standardization (http://www.iso.org) + +.. _cea861: + +CEA-861-E +========= + + +:title: A DTV Profile for Uncompressed High Speed Digital Interfaces + +:author: Consumer Electronics Association (http://www.ce.org) + +.. _vesadmt: + +VESA DMT +======== + + +:title: VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT) + +:author: Video Electronics Standards Association (http://www.vesa.org) + +.. _vesaedid: + +EDID +==== + + +:title: VESA Enhanced Extended Display Identification Data Standard +:subtitle: Release A, Revision 2 + +:author: Video Electronics Standards Association (http://www.vesa.org) + +.. _hdcp: + +HDCP +==== + + +:title: High-bandwidth Digital Content Protection System +:subtitle: Revision 1.3 + +:author: Digital Content Protection LLC (http://www.digital-cp.com) + +.. _hdmi: + +HDMI +==== + + +:title: High-Definition Multimedia Interface +:subtitle: Specification Version 1.4a + +:author: HDMI Licensing LLC (http://www.hdmi.org) + +.. _dp: + +DP +== + + +:title: VESA DisplayPort Standard +:subtitle: Version 1, Revision 2 + +:author: Video Electronics Standards Association (http://www.vesa.org) + +.. _poynton: + +poynton +======= + + +:title: Digital Video and HDTV, Algorithms and Interfaces + +:author: Charles Poynton + +.. _colimg: + +colimg +====== + + +:title: Color Imaging: Fundamentals and Applications + +:author: Erik Reinhard et al. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/buffer.rst b/Documentation/linux_tv/media/v4l/buffer.rst new file mode 100644 index 000000000000..e4cec63979c2 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/buffer.rst @@ -0,0 +1,966 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _buffer: + +******* +Buffers +******* + +A buffer contains data exchanged by application and driver using one of +the Streaming I/O methods. In the multi-planar API, the data is held in +planes, while the buffer structure acts as a container for the planes. +Only pointers to buffers (planes) are exchanged, the data itself is not +copied. These pointers, together with meta-information like timestamps +or field parity, are stored in a struct :c:type:`struct v4l2_buffer`, +argument to the :ref:`VIDIOC_QUERYBUF `, +:ref:`VIDIOC_QBUF ` and +:ref:`VIDIOC_DQBUF ` ioctl. In the multi-planar API, +some plane-specific members of struct :c:type:`struct v4l2_buffer`, +such as pointers and sizes for each plane, are stored in struct +:c:type:`struct v4l2_plane` instead. In that case, struct +:c:type:`struct v4l2_buffer` contains an array of plane structures. + +Dequeued video buffers come with timestamps. The driver decides at which +part of the frame and with which clock the timestamp is taken. Please +see flags in the masks ``V4L2_BUF_FLAG_TIMESTAMP_MASK`` and +``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` in :ref:`buffer-flags`. These flags +are always valid and constant across all buffers during the whole video +stream. Changes in these flags may take place as a side effect of +:ref:`VIDIOC_S_INPUT ` or +:ref:`VIDIOC_S_OUTPUT ` however. The +``V4L2_BUF_FLAG_TIMESTAMP_COPY`` timestamp type which is used by e.g. on +mem-to-mem devices is an exception to the rule: the timestamp source +flags are copied from the OUTPUT video buffer to the CAPTURE video +buffer. + + +.. _v4l2-buffer: + +.. flat-table:: struct v4l2_buffer + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 1 2 + + + - .. row 1 + + - __u32 + + - ``index`` + + - + - Number of the buffer, set by the application except when calling + :ref:`VIDIOC_DQBUF `, then it is set by the + driver. This field can range from zero to the number of buffers + allocated with the :ref:`VIDIOC_REQBUFS ` ioctl + (struct :ref:`v4l2_requestbuffers ` + ``count``), plus any buffers allocated with + :ref:`VIDIOC_CREATE_BUFS ` minus one. + + - .. row 2 + + - __u32 + + - ``type`` + + - + - Type of the buffer, same as struct + :ref:`v4l2_format ` ``type`` or struct + :ref:`v4l2_requestbuffers ` ``type``, set + by the application. See :ref:`v4l2-buf-type` + + - .. row 3 + + - __u32 + + - ``bytesused`` + + - + - The number of bytes occupied by the data in the buffer. It depends + on the negotiated data format and may change with each buffer for + compressed variable size data like JPEG images. Drivers must set + this field when ``type`` refers to a capture stream, applications + when it refers to an output stream. If the application sets this + to 0 for an output stream, then ``bytesused`` will be set to the + size of the buffer (see the ``length`` field of this struct) by + the driver. For multiplanar formats this field is ignored and the + ``planes`` pointer is used instead. + + - .. row 4 + + - __u32 + + - ``flags`` + + - + - Flags set by the application or driver, see :ref:`buffer-flags`. + + - .. row 5 + + - __u32 + + - ``field`` + + - + - Indicates the field order of the image in the buffer, see + :ref:`v4l2-field`. This field is not used when the buffer + contains VBI data. Drivers must set it when ``type`` refers to a + capture stream, applications when it refers to an output stream. + + - .. row 6 + + - struct timeval + + - ``timestamp`` + + - + - For capture streams this is time when the first data byte was + captured, as returned by the :c:func:`clock_gettime()` function + for the relevant clock id; see ``V4L2_BUF_FLAG_TIMESTAMP_*`` in + :ref:`buffer-flags`. For output streams the driver stores the + time at which the last data byte was actually sent out in the + ``timestamp`` field. This permits applications to monitor the + drift between the video and system clock. For output streams that + use ``V4L2_BUF_FLAG_TIMESTAMP_COPY`` the application has to fill + in the timestamp which will be copied by the driver to the capture + stream. + + - .. row 7 + + - struct :ref:`v4l2_timecode ` + + - ``timecode`` + + - + - When ``type`` is ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` and the + ``V4L2_BUF_FLAG_TIMECODE`` flag is set in ``flags``, this + structure contains a frame timecode. In + :ref:`V4L2_FIELD_ALTERNATE ` mode the top and + bottom field contain the same timecode. Timecodes are intended to + help video editing and are typically recorded on video tapes, but + also embedded in compressed formats like MPEG. This field is + independent of the ``timestamp`` and ``sequence`` fields. + + - .. row 8 + + - __u32 + + - ``sequence`` + + - + - Set by the driver, counting the frames (not fields!) in sequence. + This field is set for both input and output devices. + + - .. row 9 + + - :cspan:`3` + + In :ref:`V4L2_FIELD_ALTERNATE ` mode the top and + bottom field have the same sequence number. The count starts at + zero and includes dropped or repeated frames. A dropped frame was + received by an input device but could not be stored due to lack of + free buffer space. A repeated frame was displayed again by an + output device because the application did not pass new data in + time. + + Note this may count the frames received e.g. over USB, without + taking into account the frames dropped by the remote hardware due + to limited compression throughput or bus bandwidth. These devices + identify by not enumerating any video standards, see + :ref:`standard`. + + - .. row 10 + + - __u32 + + - ``memory`` + + - + - This field must be set by applications and/or drivers in + accordance with the selected I/O method. See :ref:`v4l2-memory` + + - .. row 11 + + - union + + - ``m`` + + - .. row 12 + + - + - __u32 + + - ``offset`` + + - For the single-planar API and when ``memory`` is + ``V4L2_MEMORY_MMAP`` this is the offset of the buffer from the + start of the device memory. The value is returned by the driver + and apart of serving as parameter to the + :ref:`mmap() ` function not useful for applications. + See :ref:`mmap` for details + + - .. row 13 + + - + - unsigned long + + - ``userptr`` + + - For the single-planar API and when ``memory`` is + ``V4L2_MEMORY_USERPTR`` this is a pointer to the buffer (casted to + unsigned long type) in virtual memory, set by the application. See + :ref:`userp` for details. + + - .. row 14 + + - + - struct v4l2_plane + + - ``*planes`` + + - When using the multi-planar API, contains a userspace pointer to + an array of struct :ref:`v4l2_plane `. The size of + the array should be put in the ``length`` field of this + :c:type:`struct v4l2_buffer` structure. + + - .. row 15 + + - + - int + + - ``fd`` + + - For the single-plane API and when ``memory`` is + ``V4L2_MEMORY_DMABUF`` this is the file descriptor associated with + a DMABUF buffer. + + - .. row 16 + + - __u32 + + - ``length`` + + - + - Size of the buffer (not the payload) in bytes for the + single-planar API. This is set by the driver based on the calls to + :ref:`VIDIOC_REQBUFS ` and/or + :ref:`VIDIOC_CREATE_BUFS `. For the + multi-planar API the application sets this to the number of + elements in the ``planes`` array. The driver will fill in the + actual number of valid elements in that array. + + - .. row 17 + + - __u32 + + - ``reserved2`` + + - + - A place holder for future extensions. Drivers and applications + must set this to 0. + + - .. row 18 + + - __u32 + + - ``reserved`` + + - + - A place holder for future extensions. Drivers and applications + must set this to 0. + + + +.. _v4l2-plane: + +.. flat-table:: struct v4l2_plane + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 1 2 + + + - .. row 1 + + - __u32 + + - ``bytesused`` + + - + - The number of bytes occupied by data in the plane (its payload). + Drivers must set this field when ``type`` refers to a capture + stream, applications when it refers to an output stream. If the + application sets this to 0 for an output stream, then + ``bytesused`` will be set to the size of the plane (see the + ``length`` field of this struct) by the driver. Note that the + actual image data starts at ``data_offset`` which may not be 0. + + - .. row 2 + + - __u32 + + - ``length`` + + - + - Size in bytes of the plane (not its payload). This is set by the + driver based on the calls to + :ref:`VIDIOC_REQBUFS ` and/or + :ref:`VIDIOC_CREATE_BUFS `. + + - .. row 3 + + - union + + - ``m`` + + - + - + + - .. row 4 + + - + - __u32 + + - ``mem_offset`` + + - When the memory type in the containing struct + :ref:`v4l2_buffer ` is ``V4L2_MEMORY_MMAP``, this + is the value that should be passed to :ref:`mmap() `, + similar to the ``offset`` field in struct + :ref:`v4l2_buffer `. + + - .. row 5 + + - + - unsigned long + + - ``userptr`` + + - When the memory type in the containing struct + :ref:`v4l2_buffer ` is ``V4L2_MEMORY_USERPTR``, + this is a userspace pointer to the memory allocated for this plane + by an application. + + - .. row 6 + + - + - int + + - ``fd`` + + - When the memory type in the containing struct + :ref:`v4l2_buffer ` is ``V4L2_MEMORY_DMABUF``, + this is a file descriptor associated with a DMABUF buffer, similar + to the ``fd`` field in struct :ref:`v4l2_buffer `. + + - .. row 7 + + - __u32 + + - ``data_offset`` + + - + - Offset in bytes to video data in the plane. Drivers must set this + field when ``type`` refers to a capture stream, applications when + it refers to an output stream. Note that data_offset is included + in ``bytesused``. So the size of the image in the plane is + ``bytesused``-``data_offset`` at offset ``data_offset`` from the + start of the plane. + + - .. row 8 + + - __u32 + + - ``reserved[11]`` + + - + - Reserved for future use. Should be zeroed by drivers and + applications. + + + +.. _v4l2-buf-type: + +.. flat-table:: enum v4l2_buf_type + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + + - .. row 1 + + - ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` + + - 1 + + - Buffer of a single-planar video capture stream, see + :ref:`capture`. + + - .. row 2 + + - ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` + + - 9 + + - Buffer of a multi-planar video capture stream, see + :ref:`capture`. + + - .. row 3 + + - ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` + + - 2 + + - Buffer of a single-planar video output stream, see + :ref:`output`. + + - .. row 4 + + - ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` + + - 10 + + - Buffer of a multi-planar video output stream, see :ref:`output`. + + - .. row 5 + + - ``V4L2_BUF_TYPE_VIDEO_OVERLAY`` + + - 3 + + - Buffer for video overlay, see :ref:`overlay`. + + - .. row 6 + + - ``V4L2_BUF_TYPE_VBI_CAPTURE`` + + - 4 + + - Buffer of a raw VBI capture stream, see :ref:`raw-vbi`. + + - .. row 7 + + - ``V4L2_BUF_TYPE_VBI_OUTPUT`` + + - 5 + + - Buffer of a raw VBI output stream, see :ref:`raw-vbi`. + + - .. row 8 + + - ``V4L2_BUF_TYPE_SLICED_VBI_CAPTURE`` + + - 6 + + - Buffer of a sliced VBI capture stream, see :ref:`sliced`. + + - .. row 9 + + - ``V4L2_BUF_TYPE_SLICED_VBI_OUTPUT`` + + - 7 + + - Buffer of a sliced VBI output stream, see :ref:`sliced`. + + - .. row 10 + + - ``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY`` + + - 8 + + - Buffer for video output overlay (OSD), see :ref:`osd`. + + - .. row 11 + + - ``V4L2_BUF_TYPE_SDR_CAPTURE`` + + - 11 + + - Buffer for Software Defined Radio (SDR) capture stream, see + :ref:`sdr`. + + - .. row 12 + + - ``V4L2_BUF_TYPE_SDR_OUTPUT`` + + - 12 + + - Buffer for Software Defined Radio (SDR) output stream, see + :ref:`sdr`. + + + +.. _buffer-flags: + +.. flat-table:: Buffer Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + + - .. row 1 + + - ``V4L2_BUF_FLAG_MAPPED`` + + - 0x00000001 + + - The buffer resides in device memory and has been mapped into the + application's address space, see :ref:`mmap` for details. + Drivers set or clear this flag when the + :ref:`VIDIOC_QUERYBUF `, + :ref:`VIDIOC_QBUF ` or + :ref:`VIDIOC_DQBUF ` ioctl is called. Set by the + driver. + + - .. row 2 + + - ``V4L2_BUF_FLAG_QUEUED`` + + - 0x00000002 + + - Internally drivers maintain two buffer queues, an incoming and + outgoing queue. When this flag is set, the buffer is currently on + the incoming queue. It automatically moves to the outgoing queue + after the buffer has been filled (capture devices) or displayed + (output devices). Drivers set or clear this flag when the + ``VIDIOC_QUERYBUF`` ioctl is called. After (successful) calling + the ``VIDIOC_QBUF``\ ioctl it is always set and after + ``VIDIOC_DQBUF`` always cleared. + + - .. row 3 + + - ``V4L2_BUF_FLAG_DONE`` + + - 0x00000004 + + - When this flag is set, the buffer is currently on the outgoing + queue, ready to be dequeued from the driver. Drivers set or clear + this flag when the ``VIDIOC_QUERYBUF`` ioctl is called. After + calling the ``VIDIOC_QBUF`` or ``VIDIOC_DQBUF`` it is always + cleared. Of course a buffer cannot be on both queues at the same + time, the ``V4L2_BUF_FLAG_QUEUED`` and ``V4L2_BUF_FLAG_DONE`` flag + are mutually exclusive. They can be both cleared however, then the + buffer is in "dequeued" state, in the application domain so to + say. + + - .. row 4 + + - ``V4L2_BUF_FLAG_ERROR`` + + - 0x00000040 + + - When this flag is set, the buffer has been dequeued successfully, + although the data might have been corrupted. This is recoverable, + streaming may continue as normal and the buffer may be reused + normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is + called. + + - .. row 5 + + - ``V4L2_BUF_FLAG_KEYFRAME`` + + - 0x00000008 + + - Drivers set or clear this flag when calling the ``VIDIOC_DQBUF`` + ioctl. It may be set by video capture devices when the buffer + contains a compressed image which is a key frame (or field), i. e. + can be decompressed on its own. Also known as an I-frame. + Applications can set this bit when ``type`` refers to an output + stream. + + - .. row 6 + + - ``V4L2_BUF_FLAG_PFRAME`` + + - 0x00000010 + + - Similar to ``V4L2_BUF_FLAG_KEYFRAME`` this flags predicted frames + or fields which contain only differences to a previous key frame. + Applications can set this bit when ``type`` refers to an output + stream. + + - .. row 7 + + - ``V4L2_BUF_FLAG_BFRAME`` + + - 0x00000020 + + - Similar to ``V4L2_BUF_FLAG_KEYFRAME`` this flags a bi-directional + predicted frame or field which contains only the differences + between the current frame and both the preceding and following key + frames to specify its content. Applications can set this bit when + ``type`` refers to an output stream. + + - .. row 8 + + - ``V4L2_BUF_FLAG_TIMECODE`` + + - 0x00000100 + + - The ``timecode`` field is valid. Drivers set or clear this flag + when the ``VIDIOC_DQBUF`` ioctl is called. Applications can set + this bit and the corresponding ``timecode`` structure when + ``type`` refers to an output stream. + + - .. row 9 + + - ``V4L2_BUF_FLAG_PREPARED`` + + - 0x00000400 + + - The buffer has been prepared for I/O and can be queued by the + application. Drivers set or clear this flag when the + :ref:`VIDIOC_QUERYBUF `, + :ref:`VIDIOC_PREPARE_BUF `, + :ref:`VIDIOC_QBUF ` or + :ref:`VIDIOC_DQBUF ` ioctl is called. + + - .. row 10 + + - ``V4L2_BUF_FLAG_NO_CACHE_INVALIDATE`` + + - 0x00000800 + + - Caches do not have to be invalidated for this buffer. Typically + applications shall use this flag if the data captured in the + buffer is not going to be touched by the CPU, instead the buffer + will, probably, be passed on to a DMA-capable hardware unit for + further processing or output. + + - .. row 11 + + - ``V4L2_BUF_FLAG_NO_CACHE_CLEAN`` + + - 0x00001000 + + - Caches do not have to be cleaned for this buffer. Typically + applications shall use this flag for output buffers if the data in + this buffer has not been created by the CPU but by some + DMA-capable unit, in which case caches have not been used. + + - .. row 12 + + - ``V4L2_BUF_FLAG_LAST`` + + - 0x00100000 + + - Last buffer produced by the hardware. mem2mem codec drivers set + this flag on the capture queue for the last buffer when the + :ref:`VIDIOC_QUERYBUF ` or + :ref:`VIDIOC_DQBUF ` ioctl is called. Due to + hardware limitations, the last buffer may be empty. In this case + the driver will set the ``bytesused`` field to 0, regardless of + the format. Any Any subsequent call to the + :ref:`VIDIOC_DQBUF ` ioctl will not block anymore, + but return an EPIPE error code. + + - .. row 13 + + - ``V4L2_BUF_FLAG_TIMESTAMP_MASK`` + + - 0x0000e000 + + - Mask for timestamp types below. To test the timestamp type, mask + out bits not belonging to timestamp type by performing a logical + and operation with buffer flags and timestamp mask. + + - .. row 14 + + - ``V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN`` + + - 0x00000000 + + - Unknown timestamp type. This type is used by drivers before Linux + 3.9 and may be either monotonic (see below) or realtime (wall + clock). Monotonic clock has been favoured in embedded systems + whereas most of the drivers use the realtime clock. Either kinds + of timestamps are available in user space via + :c:func:`clock_gettime(2)` using clock IDs ``CLOCK_MONOTONIC`` + and ``CLOCK_REALTIME``, respectively. + + - .. row 15 + + - ``V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC`` + + - 0x00002000 + + - The buffer timestamp has been taken from the ``CLOCK_MONOTONIC`` + clock. To access the same clock outside V4L2, use + :c:func:`clock_gettime(2)`. + + - .. row 16 + + - ``V4L2_BUF_FLAG_TIMESTAMP_COPY`` + + - 0x00004000 + + - The CAPTURE buffer timestamp has been taken from the corresponding + OUTPUT buffer. This flag applies only to mem2mem devices. + + - .. row 17 + + - ``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` + + - 0x00070000 + + - Mask for timestamp sources below. The timestamp source defines the + point of time the timestamp is taken in relation to the frame. + Logical 'and' operation between the ``flags`` field and + ``V4L2_BUF_FLAG_TSTAMP_SRC_MASK`` produces the value of the + timestamp source. Applications must set the timestamp source when + ``type`` refers to an output stream and + ``V4L2_BUF_FLAG_TIMESTAMP_COPY`` is set. + + - .. row 18 + + - ``V4L2_BUF_FLAG_TSTAMP_SRC_EOF`` + + - 0x00000000 + + - End Of Frame. The buffer timestamp has been taken when the last + pixel of the frame has been received or the last pixel of the + frame has been transmitted. In practice, software generated + timestamps will typically be read from the clock a small amount of + time after the last pixel has been received or transmitten, + depending on the system and other activity in it. + + - .. row 19 + + - ``V4L2_BUF_FLAG_TSTAMP_SRC_SOE`` + + - 0x00010000 + + - Start Of Exposure. The buffer timestamp has been taken when the + exposure of the frame has begun. This is only valid for the + ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type. + + + +.. _v4l2-memory: + +.. flat-table:: enum v4l2_memory + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + + - .. row 1 + + - ``V4L2_MEMORY_MMAP`` + + - 1 + + - The buffer is used for :ref:`memory mapping ` I/O. + + - .. row 2 + + - ``V4L2_MEMORY_USERPTR`` + + - 2 + + - The buffer is used for :ref:`user pointer ` I/O. + + - .. row 3 + + - ``V4L2_MEMORY_OVERLAY`` + + - 3 + + - [to do] + + - .. row 4 + + - ``V4L2_MEMORY_DMABUF`` + + - 4 + + - The buffer is used for :ref:`DMA shared buffer ` I/O. + + + +Timecodes +========= + +The :c:type:`struct v4l2_timecode` structure is designed to hold a +:ref:`smpte12m` or similar timecode. (struct +:c:type:`struct timeval` timestamps are stored in struct +:ref:`v4l2_buffer ` field ``timestamp``.) + + +.. _v4l2-timecode: + +.. flat-table:: struct v4l2_timecode + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + + - .. row 1 + + - __u32 + + - ``type`` + + - Frame rate the timecodes are based on, see :ref:`timecode-type`. + + - .. row 2 + + - __u32 + + - ``flags`` + + - Timecode flags, see :ref:`timecode-flags`. + + - .. row 3 + + - __u8 + + - ``frames`` + + - Frame count, 0 ... 23/24/29/49/59, depending on the type of + timecode. + + - .. row 4 + + - __u8 + + - ``seconds`` + + - Seconds count, 0 ... 59. This is a binary, not BCD number. + + - .. row 5 + + - __u8 + + - ``minutes`` + + - Minutes count, 0 ... 59. This is a binary, not BCD number. + + - .. row 6 + + - __u8 + + - ``hours`` + + - Hours count, 0 ... 29. This is a binary, not BCD number. + + - .. row 7 + + - __u8 + + - ``userbits``\ [4] + + - The "user group" bits from the timecode. + + + +.. _timecode-type: + +.. flat-table:: Timecode Types + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + + - .. row 1 + + - ``V4L2_TC_TYPE_24FPS`` + + - 1 + + - 24 frames per second, i. e. film. + + - .. row 2 + + - ``V4L2_TC_TYPE_25FPS`` + + - 2 + + - 25 frames per second, i. e. PAL or SECAM video. + + - .. row 3 + + - ``V4L2_TC_TYPE_30FPS`` + + - 3 + + - 30 frames per second, i. e. NTSC video. + + - .. row 4 + + - ``V4L2_TC_TYPE_50FPS`` + + - 4 + + - + + - .. row 5 + + - ``V4L2_TC_TYPE_60FPS`` + + - 5 + + - + + + +.. _timecode-flags: + +.. flat-table:: Timecode Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + + - .. row 1 + + - ``V4L2_TC_FLAG_DROPFRAME`` + + - 0x0001 + + - Indicates "drop frame" semantics for counting frames in 29.97 fps + material. When set, frame numbers 0 and 1 at the start of each + minute, except minutes 0, 10, 20, 30, 40, 50 are omitted from the + count. + + - .. row 2 + + - ``V4L2_TC_FLAG_COLORFRAME`` + + - 0x0002 + + - The "color frame" flag. + + - .. row 3 + + - ``V4L2_TC_USERBITS_field`` + + - 0x000C + + - Field mask for the "binary group flags". + + - .. row 4 + + - ``V4L2_TC_USERBITS_USERDEFINED`` + + - 0x0000 + + - Unspecified format. + + - .. row 5 + + - ``V4L2_TC_USERBITS_8BITCHARS`` + + - 0x0008 + + - 8-bit ISO characters. + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/capture-example.rst b/Documentation/linux_tv/media/v4l/capture-example.rst new file mode 100644 index 000000000000..8d35e379cea7 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/capture-example.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _capture-example: + +********************* +Video Capture Example +********************* + + +.. toctree:: + :maxdepth: 1 + + capture.c + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/capture.c.rst b/Documentation/linux_tv/media/v4l/capture.c.rst new file mode 100644 index 000000000000..41e96c78a6dd --- /dev/null +++ b/Documentation/linux_tv/media/v4l/capture.c.rst @@ -0,0 +1,675 @@ +.. -*- coding: utf-8; mode: rst -*- + +file: media/v4l/capture.c +========================= + +.. code-block:: c + + /* + * V4L2 video capture example + * + * This program can be used and distributed without restrictions. + * + * This program is provided with the V4L2 API + * see https://linuxtv.org/docs.php for more information + */ + + #include + #include + #include + #include + + #include /* getopt_long() */ + + #include /* low-level i/o */ + #include + #include + #include + #include + #include + #include + #include + + #include + + #define CLEAR(x) memset(&(x), 0, sizeof(x)) + + enum io_method { + IO_METHOD_READ, + IO_METHOD_MMAP, + IO_METHOD_USERPTR, + }; + + struct buffer { + void *start; + size_t length; + }; + + static char *dev_name; + static enum io_method io = IO_METHOD_MMAP; + static int fd = -1; + struct buffer *buffers; + static unsigned int n_buffers; + static int out_buf; + static int force_format; + static int frame_count = 70; + + static void errno_exit(const char *s) + { + fprintf(stderr, "%s error %d, %s\\n", s, errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + static int xioctl(int fh, int request, void *arg) + { + int r; + + do { + r = ioctl(fh, request, arg); + } while (-1 == r && EINTR == errno); + + return r; + } + + static void process_image(const void *p, int size) + { + if (out_buf) + fwrite(p, size, 1, stdout); + + fflush(stderr); + fprintf(stderr, "."); + fflush(stdout); + } + + static int read_frame(void) + { + struct v4l2_buffer buf; + unsigned int i; + + switch (io) { + case IO_METHOD_READ: + if (-1 == read(fd, buffers[0].start, buffers[0].length)) { + switch (errno) { + case EAGAIN: + return 0; + + case EIO: + /* Could ignore EIO, see spec. */ + + /* fall through */ + + default: + errno_exit("read"); + } + } + + process_image(buffers[0].start, buffers[0].length); + break; + + case IO_METHOD_MMAP: + CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + + if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) { + switch (errno) { + case EAGAIN: + return 0; + + case EIO: + /* Could ignore EIO, see spec. */ + + /* fall through */ + + default: + errno_exit("VIDIOC_DQBUF"); + } + } + + assert(buf.index < n_buffers); + + process_image(buffers[buf.index].start, buf.bytesused); + + if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) + errno_exit("VIDIOC_QBUF"); + break; + + case IO_METHOD_USERPTR: + CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_USERPTR; + + if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) { + switch (errno) { + case EAGAIN: + return 0; + + case EIO: + /* Could ignore EIO, see spec. */ + + /* fall through */ + + default: + errno_exit("VIDIOC_DQBUF"); + } + } + + for (i = 0; i < n_buffers; ++i) + if (buf.m.userptr == (unsigned long)buffers[i].start + && buf.length == buffers[i].length) + break; + + assert(i < n_buffers); + + process_image((void *)buf.m.userptr, buf.bytesused); + + if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) + errno_exit("VIDIOC_QBUF"); + break; + } + + return 1; + } + + static void mainloop(void) + { + unsigned int count; + + count = frame_count; + + while (count-- > 0) { + for (;;) { + fd_set fds; + struct timeval tv; + int r; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + /* Timeout. */ + tv.tv_sec = 2; + tv.tv_usec = 0; + + r = select(fd + 1, &fds, NULL, NULL, &tv); + + if (-1 == r) { + if (EINTR == errno) + continue; + errno_exit("select"); + } + + if (0 == r) { + fprintf(stderr, "select timeout\\n"); + exit(EXIT_FAILURE); + } + + if (read_frame()) + break; + /* EAGAIN - continue select loop. */ + } + } + } + + static void stop_capturing(void) + { + enum v4l2_buf_type type; + + switch (io) { + case IO_METHOD_READ: + /* Nothing to do. */ + break; + + case IO_METHOD_MMAP: + case IO_METHOD_USERPTR: + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) + errno_exit("VIDIOC_STREAMOFF"); + break; + } + } + + static void start_capturing(void) + { + unsigned int i; + enum v4l2_buf_type type; + + switch (io) { + case IO_METHOD_READ: + /* Nothing to do. */ + break; + + case IO_METHOD_MMAP: + for (i = 0; i < n_buffers; ++i) { + struct v4l2_buffer buf; + + CLEAR(buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + + if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) + errno_exit("VIDIOC_QBUF"); + } + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) + errno_exit("VIDIOC_STREAMON"); + break; + + case IO_METHOD_USERPTR: + for (i = 0; i < n_buffers; ++i) { + struct v4l2_buffer buf; + + CLEAR(buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_USERPTR; + buf.index = i; + buf.m.userptr = (unsigned long)buffers[i].start; + buf.length = buffers[i].length; + + if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) + errno_exit("VIDIOC_QBUF"); + } + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) + errno_exit("VIDIOC_STREAMON"); + break; + } + } + + static void uninit_device(void) + { + unsigned int i; + + switch (io) { + case IO_METHOD_READ: + free(buffers[0].start); + break; + + case IO_METHOD_MMAP: + for (i = 0; i < n_buffers; ++i) + if (-1 == munmap(buffers[i].start, buffers[i].length)) + errno_exit("munmap"); + break; + + case IO_METHOD_USERPTR: + for (i = 0; i < n_buffers; ++i) + free(buffers[i].start); + break; + } + + free(buffers); + } + + static void init_read(unsigned int buffer_size) + { + buffers = calloc(1, sizeof(*buffers)); + + if (!buffers) { + fprintf(stderr, "Out of memory\\n"); + exit(EXIT_FAILURE); + } + + buffers[0].length = buffer_size; + buffers[0].start = malloc(buffer_size); + + if (!buffers[0].start) { + fprintf(stderr, "Out of memory\\n"); + exit(EXIT_FAILURE); + } + } + + static void init_mmap(void) + { + struct v4l2_requestbuffers req; + + CLEAR(req); + + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; + + if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { + if (EINVAL == errno) { + fprintf(stderr, "%s does not support " + "memory mappingn", dev_name); + exit(EXIT_FAILURE); + } else { + errno_exit("VIDIOC_REQBUFS"); + } + } + + if (req.count < 2) { + fprintf(stderr, "Insufficient buffer memory on %s\\n", + dev_name); + exit(EXIT_FAILURE); + } + + buffers = calloc(req.count, sizeof(*buffers)); + + if (!buffers) { + fprintf(stderr, "Out of memory\\n"); + exit(EXIT_FAILURE); + } + + for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { + struct v4l2_buffer buf; + + CLEAR(buf); + + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = n_buffers; + + if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) + errno_exit("VIDIOC_QUERYBUF"); + + buffers[n_buffers].length = buf.length; + buffers[n_buffers].start = + mmap(NULL /* start anywhere */, + buf.length, + PROT_READ | PROT_WRITE /* required */, + MAP_SHARED /* recommended */, + fd, buf.m.offset); + + if (MAP_FAILED == buffers[n_buffers].start) + errno_exit("mmap"); + } + } + + static void init_userp(unsigned int buffer_size) + { + struct v4l2_requestbuffers req; + + CLEAR(req); + + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_USERPTR; + + if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { + if (EINVAL == errno) { + fprintf(stderr, "%s does not support " + "user pointer i/on", dev_name); + exit(EXIT_FAILURE); + } else { + errno_exit("VIDIOC_REQBUFS"); + } + } + + buffers = calloc(4, sizeof(*buffers)); + + if (!buffers) { + fprintf(stderr, "Out of memory\\n"); + exit(EXIT_FAILURE); + } + + for (n_buffers = 0; n_buffers < 4; ++n_buffers) { + buffers[n_buffers].length = buffer_size; + buffers[n_buffers].start = malloc(buffer_size); + + if (!buffers[n_buffers].start) { + fprintf(stderr, "Out of memory\\n"); + exit(EXIT_FAILURE); + } + } + } + + static void init_device(void) + { + struct v4l2_capability cap; + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + struct v4l2_format fmt; + unsigned int min; + + if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { + if (EINVAL == errno) { + fprintf(stderr, "%s is no V4L2 device\\n", + dev_name); + exit(EXIT_FAILURE); + } else { + errno_exit("VIDIOC_QUERYCAP"); + } + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + fprintf(stderr, "%s is no video capture device\\n", + dev_name); + exit(EXIT_FAILURE); + } + + switch (io) { + case IO_METHOD_READ: + if (!(cap.capabilities & V4L2_CAP_READWRITE)) { + fprintf(stderr, "%s does not support read i/o\\n", + dev_name); + exit(EXIT_FAILURE); + } + break; + + case IO_METHOD_MMAP: + case IO_METHOD_USERPTR: + if (!(cap.capabilities & V4L2_CAP_STREAMING)) { + fprintf(stderr, "%s does not support streaming i/o\\n", + dev_name); + exit(EXIT_FAILURE); + } + break; + } + + + /* Select video input, video standard and tune here. */ + + + CLEAR(cropcap); + + cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) { + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + crop.c = cropcap.defrect; /* reset to default */ + + if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) { + switch (errno) { + case EINVAL: + /* Cropping not supported. */ + break; + default: + /* Errors ignored. */ + break; + } + } + } else { + /* Errors ignored. */ + } + + + CLEAR(fmt); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (force_format) { + fmt.fmt.pix.width = 640; + fmt.fmt.pix.height = 480; + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; + + if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) + errno_exit("VIDIOC_S_FMT"); + + /* Note VIDIOC_S_FMT may change width and height. */ + } else { + /* Preserve original settings as set by v4l2-ctl for example */ + if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt)) + errno_exit("VIDIOC_G_FMT"); + } + + /* Buggy driver paranoia. */ + min = fmt.fmt.pix.width * 2; + if (fmt.fmt.pix.bytesperline < min) + fmt.fmt.pix.bytesperline = min; + min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; + if (fmt.fmt.pix.sizeimage < min) + fmt.fmt.pix.sizeimage = min; + + switch (io) { + case IO_METHOD_READ: + init_read(fmt.fmt.pix.sizeimage); + break; + + case IO_METHOD_MMAP: + init_mmap(); + break; + + case IO_METHOD_USERPTR: + init_userp(fmt.fmt.pix.sizeimage); + break; + } + } + + static void close_device(void) + { + if (-1 == close(fd)) + errno_exit("close"); + + fd = -1; + } + + static void open_device(void) + { + struct stat st; + + if (-1 == stat(dev_name, &st)) { + fprintf(stderr, "Cannot identify '%s': %d, %s\\n", + dev_name, errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + if (!S_ISCHR(st.st_mode)) { + fprintf(stderr, "%s is no devicen", dev_name); + exit(EXIT_FAILURE); + } + + fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); + + if (-1 == fd) { + fprintf(stderr, "Cannot open '%s': %d, %s\\n", + dev_name, errno, strerror(errno)); + exit(EXIT_FAILURE); + } + } + + static void usage(FILE *fp, int argc, char **argv) + { + fprintf(fp, + "Usage: %s [options]\\n\\n" + "Version 1.3\\n" + "Options:\\n" + "-d | --device name Video device name [%s]n" + "-h | --help Print this messagen" + "-m | --mmap Use memory mapped buffers [default]n" + "-r | --read Use read() callsn" + "-u | --userp Use application allocated buffersn" + "-o | --output Outputs stream to stdoutn" + "-f | --format Force format to 640x480 YUYVn" + "-c | --count Number of frames to grab [%i]n" + "", + argv[0], dev_name, frame_count); + } + + static const char short_options[] = "d:hmruofc:"; + + static const struct option + long_options[] = { + { "device", required_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "mmap", no_argument, NULL, 'm' }, + { "read", no_argument, NULL, 'r' }, + { "userp", no_argument, NULL, 'u' }, + { "output", no_argument, NULL, 'o' }, + { "format", no_argument, NULL, 'f' }, + { "count", required_argument, NULL, 'c' }, + { 0, 0, 0, 0 } + }; + + int main(int argc, char **argv) + { + dev_name = "/dev/video0"; + + for (;;) { + int idx; + int c; + + c = getopt_long(argc, argv, + short_options, long_options, &idx); + + if (-1 == c) + break; + + switch (c) { + case 0: /* getopt_long() flag */ + break; + + case 'd': + dev_name = optarg; + break; + + case 'h': + usage(stdout, argc, argv); + exit(EXIT_SUCCESS); + + case 'm': + io = IO_METHOD_MMAP; + break; + + case 'r': + io = IO_METHOD_READ; + break; + + case 'u': + io = IO_METHOD_USERPTR; + break; + + case 'o': + out_buf++; + break; + + case 'f': + force_format++; + break; + + case 'c': + errno = 0; + frame_count = strtol(optarg, NULL, 0); + if (errno) + errno_exit(optarg); + break; + + default: + usage(stderr, argc, argv); + exit(EXIT_FAILURE); + } + } + + open_device(); + init_device(); + start_capturing(); + mainloop(); + stop_capturing(); + uninit_device(); + close_device(); + fprintf(stderr, "\\n"); + return 0; + } + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/colorspaces.rst b/Documentation/linux_tv/media/v4l/colorspaces.rst new file mode 100644 index 000000000000..85d0b33b60a3 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/colorspaces.rst @@ -0,0 +1,172 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _colorspaces: + +*********** +Colorspaces +*********** + +'Color' is a very complex concept and depends on physics, chemistry and +biology. Just because you have three numbers that describe the 'red', +'green' and 'blue' components of the color of a pixel does not mean that +you can accurately display that color. A colorspace defines what it +actually *means* to have an RGB value of e.g. (255, 0, 0). That is, +which color should be reproduced on the screen in a perfectly calibrated +environment. + +In order to do that we first need to have a good definition of color, +i.e. some way to uniquely and unambiguously define a color so that +someone else can reproduce it. Human color vision is trichromatic since +the human eye has color receptors that are sensitive to three different +wavelengths of light. Hence the need to use three numbers to describe +color. Be glad you are not a mantis shrimp as those are sensitive to 12 +different wavelengths, so instead of RGB we would be using the +ABCDEFGHIJKL colorspace... + +Color exists only in the eye and brain and is the result of how strongly +color receptors are stimulated. This is based on the Spectral Power +Distribution (SPD) which is a graph showing the intensity (radiant +power) of the light at wavelengths covering the visible spectrum as it +enters the eye. The science of colorimetry is about the relationship +between the SPD and color as perceived by the human brain. + +Since the human eye has only three color receptors it is perfectly +possible that different SPDs will result in the same stimulation of +those receptors and are perceived as the same color, even though the SPD +of the light is different. + +In the 1920s experiments were devised to determine the relationship +between SPDs and the perceived color and that resulted in the CIE 1931 +standard that defines spectral weighting functions that model the +perception of color. Specifically that standard defines functions that +can take an SPD and calculate the stimulus for each color receptor. +After some further mathematical transforms these stimuli are known as +the *CIE XYZ tristimulus* values and these X, Y and Z values describe a +color as perceived by a human unambiguously. These X, Y and Z values are +all in the range [0…1]. + +The Y value in the CIE XYZ colorspace corresponds to luminance. Often +the CIE XYZ colorspace is transformed to the normalized CIE xyY +colorspace: + +x = X / (X + Y + Z) + +y = Y / (X + Y + Z) + +The x and y values are the chromaticity coordinates and can be used to +define a color without the luminance component Y. It is very confusing +to have such similar names for these colorspaces. Just be aware that if +colors are specified with lower case 'x' and 'y', then the CIE xyY +colorspace is used. Upper case 'X' and 'Y' refer to the CIE XYZ +colorspace. Also, y has nothing to do with luminance. Together x and y +specify a color, and Y the luminance. That is really all you need to +remember from a practical point of view. At the end of this section you +will find reading resources that go into much more detail if you are +interested. + +A monitor or TV will reproduce colors by emitting light at three +different wavelengths, the combination of which will stimulate the color +receptors in the eye and thus cause the perception of color. +Historically these wavelengths were defined by the red, green and blue +phosphors used in the displays. These *color primaries* are part of what +defines a colorspace. + +Different display devices will have different primaries and some +primaries are more suitable for some display technologies than others. +This has resulted in a variety of colorspaces that are used for +different display technologies or uses. To define a colorspace you need +to define the three color primaries (these are typically defined as x, y +chromaticity coordinates from the CIE xyY colorspace) but also the white +reference: that is the color obtained when all three primaries are at +maximum power. This determines the relative power or energy of the +primaries. This is usually chosen to be close to daylight which has been +defined as the CIE D65 Illuminant. + +To recapitulate: the CIE XYZ colorspace uniquely identifies colors. +Other colorspaces are defined by three chromaticity coordinates defined +in the CIE xyY colorspace. Based on those a 3x3 matrix can be +constructed that transforms CIE XYZ colors to colors in the new +colorspace. + +Both the CIE XYZ and the RGB colorspace that are derived from the +specific chromaticity primaries are linear colorspaces. But neither the +eye, nor display technology is linear. Doubling the values of all +components in the linear colorspace will not be perceived as twice the +intensity of the color. So each colorspace also defines a transfer +function that takes a linear color component value and transforms it to +the non-linear component value, which is a closer match to the +non-linear performance of both the eye and displays. Linear component +values are denoted RGB, non-linear are denoted as R'G'B'. In general +colors used in graphics are all R'G'B', except in openGL which uses +linear RGB. Special care should be taken when dealing with openGL to +provide linear RGB colors or to use the built-in openGL support to apply +the inverse transfer function. + +The final piece that defines a colorspace is a function that transforms +non-linear R'G'B' to non-linear Y'CbCr. This function is determined by +the so-called luma coefficients. There may be multiple possible Y'CbCr +encodings allowed for the same colorspace. Many encodings of color +prefer to use luma (Y') and chroma (CbCr) instead of R'G'B'. Since the +human eye is more sensitive to differences in luminance than in color +this encoding allows one to reduce the amount of color information +compared to the luma data. Note that the luma (Y') is unrelated to the Y +in the CIE XYZ colorspace. Also note that Y'CbCr is often called YCbCr +or YUV even though these are strictly speaking wrong. + +Sometimes people confuse Y'CbCr as being a colorspace. This is not +correct, it is just an encoding of an R'G'B' color into luma and chroma +values. The underlying colorspace that is associated with the R'G'B' +color is also associated with the Y'CbCr color. + +The final step is how the RGB, R'G'B' or Y'CbCr values are quantized. +The CIE XYZ colorspace where X, Y and Z are in the range [0…1] describes +all colors that humans can perceive, but the transform to another +colorspace will produce colors that are outside the [0…1] range. Once +clamped to the [0…1] range those colors can no longer be reproduced in +that colorspace. This clamping is what reduces the extent or gamut of +the colorspace. How the range of [0…1] is translated to integer values +in the range of [0…255] (or higher, depending on the color depth) is +called the quantization. This is *not* part of the colorspace +definition. In practice RGB or R'G'B' values are full range, i.e. they +use the full [0…255] range. Y'CbCr values on the other hand are limited +range with Y' using [16…235] and Cb and Cr using [16…240]. + +Unfortunately, in some cases limited range RGB is also used where the +components use the range [16…235]. And full range Y'CbCr also exists +using the [0…255] range. + +In order to correctly interpret a color you need to know the +quantization range, whether it is R'G'B' or Y'CbCr, the used Y'CbCr +encoding and the colorspace. From that information you can calculate the +corresponding CIE XYZ color and map that again to whatever colorspace +your display device uses. + +The colorspace definition itself consists of the three chromaticity +primaries, the white reference chromaticity, a transfer function and the +luma coefficients needed to transform R'G'B' to Y'CbCr. While some +colorspace standards correctly define all four, quite often the +colorspace standard only defines some, and you have to rely on other +standards for the missing pieces. The fact that colorspaces are often a +mix of different standards also led to very confusing naming conventions +where the name of a standard was used to name a colorspace when in fact +that standard was part of various other colorspaces as well. + +If you want to read more about colors and colorspaces, then the +following resources are useful: :ref:`poynton` is a good practical +book for video engineers, :ref:`colimg` has a much broader scope and +describes many more aspects of color (physics, chemistry, biology, +etc.). The +`http://www.brucelindbloom.com `__ +website is an excellent resource, especially with respect to the +mathematics behind colorspace conversions. The wikipedia +`CIE 1931 colorspace `__ +article is also very useful. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/common-defs.rst b/Documentation/linux_tv/media/v4l/common-defs.rst new file mode 100644 index 000000000000..3f90a8c6e28c --- /dev/null +++ b/Documentation/linux_tv/media/v4l/common-defs.rst @@ -0,0 +1,24 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _common-defs: + +****************************************************** +Common definitions for V4L2 and V4L2 subdev interfaces +****************************************************** + + +.. toctree:: + :maxdepth: 1 + + selections-common + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/common.rst b/Documentation/linux_tv/media/v4l/common.rst new file mode 100644 index 000000000000..0e85b46b2efc --- /dev/null +++ b/Documentation/linux_tv/media/v4l/common.rst @@ -0,0 +1,56 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _common: + +################### +Common API Elements +################### +Programming a V4L2 device consists of these steps: + +- Opening the device + +- Changing device properties, selecting a video and audio input, video + standard, picture brightness a. o. + +- Negotiating a data format + +- Negotiating an input/output method + +- The actual input/output loop + +- Closing the device + +In practice most steps are optional and can be executed out of order. It +depends on the V4L2 device type, you can read about the details in +:ref:`devices`. In this chapter we will discuss the basic concepts +applicable to all devices. + + +.. toctree:: + :maxdepth: 1 + + open + querycap + app-pri + video + audio + tuner + standard + dv-timings + controls + format + planar-apis + crop + selection-api + streaming-par + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/compat.rst b/Documentation/linux_tv/media/v4l/compat.rst new file mode 100644 index 000000000000..8a6d883ae6af --- /dev/null +++ b/Documentation/linux_tv/media/v4l/compat.rst @@ -0,0 +1,29 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _compat: + +******* +Changes +******* + +The following chapters document the evolution of the V4L2 API, errata or +extensions. They are also intended to help application and driver +writers to port or update their code. + + +.. toctree:: + :maxdepth: 1 + + diff-v4l + hist-v4l2 + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/control.rst b/Documentation/linux_tv/media/v4l/control.rst new file mode 100644 index 000000000000..16eb34472892 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/control.rst @@ -0,0 +1,536 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _control: + +************* +User Controls +************* + +Devices typically have a number of user-settable controls such as +brightness, saturation and so on, which would be presented to the user +on a graphical user interface. But, different devices will have +different controls available, and furthermore, the range of possible +values, and the default value will vary from device to device. The +control ioctls provide the information and a mechanism to create a nice +user interface for these controls that will work correctly with any +device. + +All controls are accessed using an ID value. V4L2 defines several IDs +for specific purposes. Drivers can also implement their own custom +controls using ``V4L2_CID_PRIVATE_BASE`` [1]_ and higher values. The +pre-defined control IDs have the prefix ``V4L2_CID_``, and are listed in +:ref:`control-id`. The ID is used when querying the attributes of a +control, and when getting or setting the current value. + +Generally applications should present controls to the user without +assumptions about their purpose. Each control comes with a name string +the user is supposed to understand. When the purpose is non-intuitive +the driver writer should provide a user manual, a user interface plug-in +or a driver specific panel application. Predefined IDs were introduced +to change a few controls programmatically, for example to mute a device +during a channel switch. + +Drivers may enumerate different controls after switching the current +video input or output, tuner or modulator, or audio input or output. +Different in the sense of other bounds, another default and current +value, step size or other menu items. A control with a certain *custom* +ID can also change name and type. + +If a control is not applicable to the current configuration of the +device (for example, it doesn't apply to the current video input) +drivers set the ``V4L2_CTRL_FLAG_INACTIVE`` flag. + +Control values are stored globally, they do not change when switching +except to stay within the reported bounds. They also do not change e. g. +when the device is opened or closed, when the tuner radio frequency is +changed or generally never without application request. + +V4L2 specifies an event mechanism to notify applications when controls +change value (see +:ref:`VIDIOC_SUBSCRIBE_EVENT `, event +``V4L2_EVENT_CTRL``), panel applications might want to make use of that +in order to always reflect the correct control value. + +All controls use machine endianness. + + +.. _control-id: + +Control IDs +=========== + +``V4L2_CID_BASE`` + First predefined ID, equal to ``V4L2_CID_BRIGHTNESS``. + +``V4L2_CID_USER_BASE`` + Synonym of ``V4L2_CID_BASE``. + +``V4L2_CID_BRIGHTNESS`` ``(integer)`` + Picture brightness, or more precisely, the black level. + +``V4L2_CID_CONTRAST`` ``(integer)`` + Picture contrast or luma gain. + +``V4L2_CID_SATURATION`` ``(integer)`` + Picture color saturation or chroma gain. + +``V4L2_CID_HUE`` ``(integer)`` + Hue or color balance. + +``V4L2_CID_AUDIO_VOLUME`` ``(integer)`` + Overall audio volume. Note some drivers also provide an OSS or ALSA + mixer interface. + +``V4L2_CID_AUDIO_BALANCE`` ``(integer)`` + Audio stereo balance. Minimum corresponds to all the way left, + maximum to right. + +``V4L2_CID_AUDIO_BASS`` ``(integer)`` + Audio bass adjustment. + +``V4L2_CID_AUDIO_TREBLE`` ``(integer)`` + Audio treble adjustment. + +``V4L2_CID_AUDIO_MUTE`` ``(boolean)`` + Mute audio, i. e. set the volume to zero, however without affecting + ``V4L2_CID_AUDIO_VOLUME``. Like ALSA drivers, V4L2 drivers must mute + at load time to avoid excessive noise. Actually the entire device + should be reset to a low power consumption state. + +``V4L2_CID_AUDIO_LOUDNESS`` ``(boolean)`` + Loudness mode (bass boost). + +``V4L2_CID_BLACK_LEVEL`` ``(integer)`` + Another name for brightness (not a synonym of + ``V4L2_CID_BRIGHTNESS``). This control is deprecated and should not + be used in new drivers and applications. + +``V4L2_CID_AUTO_WHITE_BALANCE`` ``(boolean)`` + Automatic white balance (cameras). + +``V4L2_CID_DO_WHITE_BALANCE`` ``(button)`` + This is an action control. When set (the value is ignored), the + device will do a white balance and then hold the current setting. + Contrast this with the boolean ``V4L2_CID_AUTO_WHITE_BALANCE``, + which, when activated, keeps adjusting the white balance. + +``V4L2_CID_RED_BALANCE`` ``(integer)`` + Red chroma balance. + +``V4L2_CID_BLUE_BALANCE`` ``(integer)`` + Blue chroma balance. + +``V4L2_CID_GAMMA`` ``(integer)`` + Gamma adjust. + +``V4L2_CID_WHITENESS`` ``(integer)`` + Whiteness for grey-scale devices. This is a synonym for + ``V4L2_CID_GAMMA``. This control is deprecated and should not be + used in new drivers and applications. + +``V4L2_CID_EXPOSURE`` ``(integer)`` + Exposure (cameras). [Unit?] + +``V4L2_CID_AUTOGAIN`` ``(boolean)`` + Automatic gain/exposure control. + +``V4L2_CID_GAIN`` ``(integer)`` + Gain control. + +``V4L2_CID_HFLIP`` ``(boolean)`` + Mirror the picture horizontally. + +``V4L2_CID_VFLIP`` ``(boolean)`` + Mirror the picture vertically. + +.. _`v4l2-power-line-frequency`: + +``V4L2_CID_POWER_LINE_FREQUENCY`` ``(enum)`` + Enables a power line frequency filter to avoid flicker. Possible + values for ``enum v4l2_power_line_frequency`` are: + ``V4L2_CID_POWER_LINE_FREQUENCY_DISABLED`` (0), + ``V4L2_CID_POWER_LINE_FREQUENCY_50HZ`` (1), + ``V4L2_CID_POWER_LINE_FREQUENCY_60HZ`` (2) and + ``V4L2_CID_POWER_LINE_FREQUENCY_AUTO`` (3). + +``V4L2_CID_HUE_AUTO`` ``(boolean)`` + Enables automatic hue control by the device. The effect of setting + ``V4L2_CID_HUE`` while automatic hue control is enabled is + undefined, drivers should ignore such request. + +``V4L2_CID_WHITE_BALANCE_TEMPERATURE`` ``(integer)`` + This control specifies the white balance settings as a color + temperature in Kelvin. A driver should have a minimum of 2800 + (incandescent) to 6500 (daylight). For more information about color + temperature see + `Wikipedia `__. + +``V4L2_CID_SHARPNESS`` ``(integer)`` + Adjusts the sharpness filters in a camera. The minimum value + disables the filters, higher values give a sharper picture. + +``V4L2_CID_BACKLIGHT_COMPENSATION`` ``(integer)`` + Adjusts the backlight compensation in a camera. The minimum value + disables backlight compensation. + +``V4L2_CID_CHROMA_AGC`` ``(boolean)`` + Chroma automatic gain control. + +``V4L2_CID_CHROMA_GAIN`` ``(integer)`` + Adjusts the Chroma gain control (for use when chroma AGC is + disabled). + +``V4L2_CID_COLOR_KILLER`` ``(boolean)`` + Enable the color killer (i. e. force a black & white image in case + of a weak video signal). + +.. _`v4l2-colorfx`: + +``V4L2_CID_COLORFX`` ``(enum)`` + Selects a color effect. The following values are defined: + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. row 1 + + - ``V4L2_COLORFX_NONE`` + + - Color effect is disabled. + + - .. row 2 + + - ``V4L2_COLORFX_ANTIQUE`` + + - An aging (old photo) effect. + + - .. row 3 + + - ``V4L2_COLORFX_ART_FREEZE`` + + - Frost color effect. + + - .. row 4 + + - ``V4L2_COLORFX_AQUA`` + + - Water color, cool tone. + + - .. row 5 + + - ``V4L2_COLORFX_BW`` + + - Black and white. + + - .. row 6 + + - ``V4L2_COLORFX_EMBOSS`` + + - Emboss, the highlights and shadows replace light/dark boundaries + and low contrast areas are set to a gray background. + + - .. row 7 + + - ``V4L2_COLORFX_GRASS_GREEN`` + + - Grass green. + + - .. row 8 + + - ``V4L2_COLORFX_NEGATIVE`` + + - Negative. + + - .. row 9 + + - ``V4L2_COLORFX_SEPIA`` + + - Sepia tone. + + - .. row 10 + + - ``V4L2_COLORFX_SKETCH`` + + - Sketch. + + - .. row 11 + + - ``V4L2_COLORFX_SKIN_WHITEN`` + + - Skin whiten. + + - .. row 12 + + - ``V4L2_COLORFX_SKY_BLUE`` + + - Sky blue. + + - .. row 13 + + - ``V4L2_COLORFX_SOLARIZATION`` + + - Solarization, the image is partially reversed in tone, only color + values above or below a certain threshold are inverted. + + - .. row 14 + + - ``V4L2_COLORFX_SILHOUETTE`` + + - Silhouette (outline). + + - .. row 15 + + - ``V4L2_COLORFX_VIVID`` + + - Vivid colors. + + - .. row 16 + + - ``V4L2_COLORFX_SET_CBCR`` + + - The Cb and Cr chroma components are replaced by fixed coefficients + determined by ``V4L2_CID_COLORFX_CBCR`` control. + + + +``V4L2_CID_COLORFX_CBCR`` ``(integer)`` + Determines the Cb and Cr coefficients for ``V4L2_COLORFX_SET_CBCR`` + color effect. Bits [7:0] of the supplied 32 bit value are + interpreted as Cr component, bits [15:8] as Cb component and bits + [31:16] must be zero. + +``V4L2_CID_AUTOBRIGHTNESS`` ``(boolean)`` + Enable Automatic Brightness. + +``V4L2_CID_ROTATE`` ``(integer)`` + Rotates the image by specified angle. Common angles are 90, 270 and + 180. Rotating the image to 90 and 270 will reverse the height and + width of the display window. It is necessary to set the new height + and width of the picture using the + :ref:`VIDIOC_S_FMT ` ioctl according to the + rotation angle selected. + +``V4L2_CID_BG_COLOR`` ``(integer)`` + Sets the background color on the current output device. Background + color needs to be specified in the RGB24 format. The supplied 32 bit + value is interpreted as bits 0-7 Red color information, bits 8-15 + Green color information, bits 16-23 Blue color information and bits + 24-31 must be zero. + +``V4L2_CID_ILLUMINATORS_1 V4L2_CID_ILLUMINATORS_2`` ``(boolean)`` + Switch on or off the illuminator 1 or 2 of the device (usually a + microscope). + +``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE`` ``(integer)`` + This is a read-only control that can be read by the application and + used as a hint to determine the number of CAPTURE buffers to pass to + REQBUFS. The value is the minimum number of CAPTURE buffers that is + necessary for hardware to work. + +``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT`` ``(integer)`` + This is a read-only control that can be read by the application and + used as a hint to determine the number of OUTPUT buffers to pass to + REQBUFS. The value is the minimum number of OUTPUT buffers that is + necessary for hardware to work. + +.. _`v4l2-alpha-component`: + +``V4L2_CID_ALPHA_COMPONENT`` ``(integer)`` + Sets the alpha color component. When a capture device (or capture + queue of a mem-to-mem device) produces a frame format that includes + an alpha component (e.g. + :ref:`packed RGB image formats `) and the alpha value + is not defined by the device or the mem-to-mem input data this + control lets you select the alpha component value of all pixels. + When an output device (or output queue of a mem-to-mem device) + consumes a frame format that doesn't include an alpha component and + the device supports alpha channel processing this control lets you + set the alpha component value of all pixels for further processing + in the device. + +``V4L2_CID_LASTP1`` + End of the predefined control IDs (currently + ``V4L2_CID_ALPHA_COMPONENT`` + 1). + +``V4L2_CID_PRIVATE_BASE`` + ID of the first custom (driver specific) control. Applications + depending on particular custom controls should check the driver name + and version, see :ref:`querycap`. + +Applications can enumerate the available controls with the +:ref:`VIDIOC_QUERYCTRL ` and +:ref:`VIDIOC_QUERYMENU ` ioctls, get and set a +control value with the :ref:`VIDIOC_G_CTRL ` and +:ref:`VIDIOC_S_CTRL ` ioctls. Drivers must implement +``VIDIOC_QUERYCTRL``, ``VIDIOC_G_CTRL`` and ``VIDIOC_S_CTRL`` when the +device has one or more controls, ``VIDIOC_QUERYMENU`` when it has one or +more menu type controls. + + +.. code-block:: c + + struct v4l2_queryctrl queryctrl; + struct v4l2_querymenu querymenu; + + static void enumerate_menu(void) + { + printf(" Menu items:\\n"); + + memset(&querymenu, 0, sizeof(querymenu)); + querymenu.id = queryctrl.id; + + for (querymenu.index = queryctrl.minimum; + querymenu.index <= queryctrl.maximum; + querymenu.index++) { + if (0 == ioctl(fd, VIDIOC_QUERYMENU, &querymenu)) { + printf(" %s\\n", querymenu.name); + } + } + } + + memset(&queryctrl, 0, sizeof(queryctrl)); + + for (queryctrl.id = V4L2_CID_BASE; + queryctrl.id < V4L2_CID_LASTP1; + queryctrl.id++) { + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) { + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + continue; + + printf("Control %s\\n", queryctrl.name); + + if (queryctrl.type == V4L2_CTRL_TYPE_MENU) + enumerate_menu(); + } else { + if (errno == EINVAL) + continue; + + perror("VIDIOC_QUERYCTRL"); + exit(EXIT_FAILURE); + } + } + + for (queryctrl.id = V4L2_CID_PRIVATE_BASE;; + queryctrl.id++) { + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) { + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + continue; + + printf("Control %s\\n", queryctrl.name); + + if (queryctrl.type == V4L2_CTRL_TYPE_MENU) + enumerate_menu(); + } else { + if (errno == EINVAL) + break; + + perror("VIDIOC_QUERYCTRL"); + exit(EXIT_FAILURE); + } + } + + +.. code-block:: c + + memset(&queryctrl, 0, sizeof(queryctrl)); + + queryctrl.id = V4L2_CTRL_CLASS_USER | V4L2_CTRL_FLAG_NEXT_CTRL; + while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) { + if (V4L2_CTRL_ID2CLASS(queryctrl.id) != V4L2_CTRL_CLASS_USER) + break; + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) + continue; + + printf("Control %s\\n", queryctrl.name); + + if (queryctrl.type == V4L2_CTRL_TYPE_MENU) + enumerate_menu(); + + queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + } + if (errno != EINVAL) { + perror("VIDIOC_QUERYCTRL"); + exit(EXIT_FAILURE); + } + + +.. code-block:: c + + struct v4l2_queryctrl queryctrl; + struct v4l2_control control; + + memset(&queryctrl, 0, sizeof(queryctrl)); + queryctrl.id = V4L2_CID_BRIGHTNESS; + + if (-1 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) { + if (errno != EINVAL) { + perror("VIDIOC_QUERYCTRL"); + exit(EXIT_FAILURE); + } else { + printf("V4L2_CID_BRIGHTNESS is not supportedn"); + } + } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { + printf("V4L2_CID_BRIGHTNESS is not supportedn"); + } else { + memset(&control, 0, sizeof (control)); + control.id = V4L2_CID_BRIGHTNESS; + control.value = queryctrl.default_value; + + if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)) { + perror("VIDIOC_S_CTRL"); + exit(EXIT_FAILURE); + } + } + + memset(&control, 0, sizeof(control)); + control.id = V4L2_CID_CONTRAST; + + if (0 == ioctl(fd, VIDIOC_G_CTRL, &control)) { + control.value += 1; + + /* The driver may clamp the value or return ERANGE, ignored here */ + + if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control) + && errno != ERANGE) { + perror("VIDIOC_S_CTRL"); + exit(EXIT_FAILURE); + } + /* Ignore if V4L2_CID_CONTRAST is unsupported */ + } else if (errno != EINVAL) { + perror("VIDIOC_G_CTRL"); + exit(EXIT_FAILURE); + } + + control.id = V4L2_CID_AUDIO_MUTE; + control.value = 1; /* silence */ + + /* Errors ignored */ + ioctl(fd, VIDIOC_S_CTRL, &control); + +.. [1] + The use of ``V4L2_CID_PRIVATE_BASE`` is problematic because different + drivers may use the same ``V4L2_CID_PRIVATE_BASE`` ID for different + controls. This makes it hard to programatically set such controls + since the meaning of the control with that ID is driver dependent. In + order to resolve this drivers use unique IDs and the + ``V4L2_CID_PRIVATE_BASE`` IDs are mapped to those unique IDs by the + kernel. Consider these ``V4L2_CID_PRIVATE_BASE`` IDs as aliases to + the real IDs. + + Many applications today still use the ``V4L2_CID_PRIVATE_BASE`` IDs + instead of using :ref:`VIDIOC_QUERYCTRL ` with + the ``V4L2_CTRL_FLAG_NEXT_CTRL`` flag to enumerate all IDs, so + support for ``V4L2_CID_PRIVATE_BASE`` is still around. + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/controls.rst b/Documentation/linux_tv/media/v4l/controls.rst new file mode 100644 index 000000000000..fe5bca543699 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/controls.rst @@ -0,0 +1,18 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. toctree:: + :maxdepth: 1 + + control + extended-controls + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/crop.rst b/Documentation/linux_tv/media/v4l/crop.rst new file mode 100644 index 000000000000..b9014d03865f --- /dev/null +++ b/Documentation/linux_tv/media/v4l/crop.rst @@ -0,0 +1,300 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _crop: + +************************************* +Image Cropping, Insertion and Scaling +************************************* + +Some video capture devices can sample a subsection of the picture and +shrink or enlarge it to an image of arbitrary size. We call these +abilities cropping and scaling. Some video output devices can scale an +image up or down and insert it at an arbitrary scan line and horizontal +offset into a video signal. + +Applications can use the following API to select an area in the video +signal, query the default area and the hardware limits. *Despite their +name, the :ref:`VIDIOC_CROPCAP `, +:ref:`VIDIOC_G_CROP ` and +:ref:`VIDIOC_S_CROP ` ioctls apply to input as well +as output devices.* + +Scaling requires a source and a target. On a video capture or overlay +device the source is the video signal, and the cropping ioctls determine +the area actually sampled. The target are images read by the application +or overlaid onto the graphics screen. Their size (and position for an +overlay) is negotiated with the :ref:`VIDIOC_G_FMT ` +and :ref:`VIDIOC_S_FMT ` ioctls. + +On a video output device the source are the images passed in by the +application, and their size is again negotiated with the +``VIDIOC_G/S_FMT`` ioctls, or may be encoded in a compressed video +stream. The target is the video signal, and the cropping ioctls +determine the area where the images are inserted. + +Source and target rectangles are defined even if the device does not +support scaling or the ``VIDIOC_G/S_CROP`` ioctls. Their size (and +position where applicable) will be fixed in this case. *All capture and +output device must support the ``VIDIOC_CROPCAP`` ioctl such that +applications can determine if scaling takes place.* + + +Cropping Structures +=================== + + +.. _crop-scale: + +.. figure:: crop_files/crop.* + :alt: crop.pdf / crop.gif + :align: center + + Image Cropping, Insertion and Scaling + + The cropping, insertion and scaling process + + + +For capture devices the coordinates of the top left corner, width and +height of the area which can be sampled is given by the ``bounds`` +substructure of the struct :ref:`v4l2_cropcap ` +returned by the ``VIDIOC_CROPCAP`` ioctl. To support a wide range of +hardware this specification does not define an origin or units. However +by convention drivers should horizontally count unscaled samples +relative to 0H (the leading edge of the horizontal sync pulse, see +:ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field +(:ref:`vbi-525`, :ref:`vbi-625`), multiplied by two if the driver +can capture both fields. + +The top left corner, width and height of the source rectangle, that is +the area actually sampled, is given by struct +:ref:`v4l2_crop ` using the same coordinate system as +struct :ref:`v4l2_cropcap `. Applications can use the +``VIDIOC_G_CROP`` and ``VIDIOC_S_CROP`` ioctls to get and set this +rectangle. It must lie completely within the capture boundaries and the +driver may further adjust the requested size and/or position according +to hardware limitations. + +Each capture device has a default source rectangle, given by the +``defrect`` substructure of struct +:ref:`v4l2_cropcap `. The center of this rectangle +shall align with the center of the active picture area of the video +signal, and cover what the driver writer considers the complete picture. +Drivers shall reset the source rectangle to the default when the driver +is first loaded, but not later. + +For output devices these structures and ioctls are used accordingly, +defining the *target* rectangle where the images will be inserted into +the video signal. + + +Scaling Adjustments +=================== + +Video hardware can have various cropping, insertion and scaling +limitations. It may only scale up or down, support only discrete scaling +factors, or have different scaling abilities in horizontal and vertical +direction. Also it may not support scaling at all. At the same time the +struct :ref:`v4l2_crop ` rectangle may have to be aligned, +and both the source and target rectangles may have arbitrary upper and +lower size limits. In particular the maximum ``width`` and ``height`` in +struct :ref:`v4l2_crop ` may be smaller than the struct +:ref:`v4l2_cropcap `. ``bounds`` area. Therefore, as +usual, drivers are expected to adjust the requested parameters and +return the actual values selected. + +Applications can change the source or the target rectangle first, as +they may prefer a particular image size or a certain area in the video +signal. If the driver has to adjust both to satisfy hardware +limitations, the last requested rectangle shall take priority, and the +driver should preferably adjust the opposite one. The +:ref:`VIDIOC_TRY_FMT ` ioctl however shall not change +the driver state and therefore only adjust the requested rectangle. + +Suppose scaling on a video capture device is restricted to a factor 1:1 +or 2:1 in either direction and the target image size must be a multiple +of 16 × 16 pixels. The source cropping rectangle is set to defaults, +which are also the upper limit in this example, of 640 × 400 pixels at +offset 0, 0. An application requests an image size of 300 × 225 pixels, +assuming video will be scaled down from the "full picture" accordingly. +The driver sets the image size to the closest possible values 304 × 224, +then chooses the cropping rectangle closest to the requested size, that +is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is +still valid, thus unmodified. Given the default cropping rectangle +reported by ``VIDIOC_CROPCAP`` the application can easily propose +another offset to center the cropping rectangle. + +Now the application may insist on covering an area using a picture +aspect ratio closer to the original request, so it asks for a cropping +rectangle of 608 × 456 pixels. The present scaling factors limit +cropping to 640 × 384, so the driver returns the cropping size 608 × 384 +and adjusts the image size to closest possible 304 × 192. + + +Examples +======== + +Source and target rectangles shall remain unchanged across closing and +reopening a device, such that piping data into or out of a device will +work without special preparations. More advanced applications should +ensure the parameters are suitable before starting I/O. + +(A video capture device is assumed; change +``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other devices.) + + +.. code-block:: c + + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + + memset (&cropcap, 0, sizeof (cropcap)); + cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) { + perror ("VIDIOC_CROPCAP"); + exit (EXIT_FAILURE); + } + + memset (&crop, 0, sizeof (crop)); + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + crop.c = cropcap.defrect; + + /* Ignore if cropping is not supported (EINVAL). */ + + if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop) + && errno != EINVAL) { + perror ("VIDIOC_S_CROP"); + exit (EXIT_FAILURE); + } + +(A video capture device is assumed.) + + +.. code-block:: c + + struct v4l2_cropcap cropcap; + struct v4l2_format format; + + reset_cropping_parameters (); + + /* Scale down to 1/4 size of full picture. */ + + memset (&format, 0, sizeof (format)); /* defaults */ + + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + format.fmt.pix.width = cropcap.defrect.width >> 1; + format.fmt.pix.height = cropcap.defrect.height >> 1; + format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + + if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) { + perror ("VIDIOC_S_FORMAT"); + exit (EXIT_FAILURE); + } + + /* We could check the actual image size now, the actual scaling factor + or if the driver can scale at all. */ + + +.. code-block:: c + + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + + memset (&cropcap, 0, sizeof (cropcap)); + cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) { + perror ("VIDIOC_CROPCAP"); + exit (EXIT_FAILURE); + } + + memset (&crop, 0, sizeof (crop)); + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + crop.c = cropcap.defrect; + + /* Scale the width and height to 50 % of their original size + and center the output. */ + + crop.c.width /= 2; + crop.c.height /= 2; + crop.c.left += crop.c.width / 2; + crop.c.top += crop.c.height / 2; + + /* Ignore if cropping is not supported (EINVAL). */ + + if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop) + && errno != EINVAL) { + perror ("VIDIOC_S_CROP"); + exit (EXIT_FAILURE); + } + +(A video capture device is assumed.) + + +.. code-block:: c + + struct v4l2_cropcap cropcap; + struct v4l2_crop crop; + struct v4l2_format format; + double hscale, vscale; + double aspect; + int dwidth, dheight; + + memset (&cropcap, 0, sizeof (cropcap)); + cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) { + perror ("VIDIOC_CROPCAP"); + exit (EXIT_FAILURE); + } + + memset (&crop, 0, sizeof (crop)); + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) { + if (errno != EINVAL) { + perror ("VIDIOC_G_CROP"); + exit (EXIT_FAILURE); + } + + /* Cropping not supported. */ + crop.c = cropcap.defrect; + } + + memset (&format, 0, sizeof (format)); + format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) { + perror ("VIDIOC_G_FMT"); + exit (EXIT_FAILURE); + } + + /* The scaling applied by the driver. */ + + hscale = format.fmt.pix.width / (double) crop.c.width; + vscale = format.fmt.pix.height / (double) crop.c.height; + + aspect = cropcap.pixelaspect.numerator / + (double) cropcap.pixelaspect.denominator; + aspect = aspect * hscale / vscale; + + /* Devices following ITU-R BT.601 do not capture + square pixels. For playback on a computer monitor + we should scale the images to this size. */ + + dwidth = format.fmt.pix.width / aspect; + dheight = format.fmt.pix.height; + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/crop_files/crop.gif b/Documentation/linux_tv/media/v4l/crop_files/crop.gif new file mode 100644 index 000000000000..3b9e7d836d4b Binary files /dev/null and b/Documentation/linux_tv/media/v4l/crop_files/crop.gif differ diff --git a/Documentation/linux_tv/media/v4l/crop_files/crop.pdf b/Documentation/linux_tv/media/v4l/crop_files/crop.pdf new file mode 100644 index 000000000000..c9fb81cd32f3 Binary files /dev/null and b/Documentation/linux_tv/media/v4l/crop_files/crop.pdf differ diff --git a/Documentation/linux_tv/media/v4l/depth-formats.rst b/Documentation/linux_tv/media/v4l/depth-formats.rst new file mode 100644 index 000000000000..c363eaf741f5 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/depth-formats.rst @@ -0,0 +1,26 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _depth-formats: + +************* +Depth Formats +************* + +Depth data provides distance to points, mapped onto the image plane + + +.. toctree:: + :maxdepth: 1 + + pixfmt-z16 + + + + +.. ------------------------------------------------------------------------------ +.. This file was automatically converted from DocBook-XML with the dbxml +.. library (https://github.com/return42/sphkerneldoc). The origin XML comes +.. from the linux kernel, refer to: +.. +.. * https://github.com/torvalds/linux/tree/master/Documentation/DocBook +.. ------------------------------------------------------------------------------ diff --git a/Documentation/linux_tv/media/v4l/dev-capture.rst b/Documentation/linux_tv/media/v4l/dev-capture.rst new file mode 100644 index 000000000000..21207ab2e604 --- /dev/null +++ b/Documentation/linux_tv/media/v4l/dev-capture.rst @@ -0,0 +1,111 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _capture: + +*********************** +Video Capture Interface +*********************** + +Video capture devices sample an analog video signal and store the +digitized images in memory. Today nearly all devices can capture at full +25 or 30 frames/second. With this interface applications can control the +capture process and move images from the driver into user space. + +Conventionally V4L2 video capture devices are accessed through character +device special files named ``/dev/video`` and ``/dev/video0`` to +``/dev/video63`` with major number 81 and minor numbers 0 to 63. +``/dev/video`` is typically a symbolic link to the preferred video +device. Note the same device files are used for video output devices. + + +Querying Capabilities +===================== + +Devices supporting the video capture interface set the +``V4L2_CAP_VIDEO_CAPTURE`` or ``V4L2_CAP_VIDEO_CAPTURE_MPLANE`` flag in +the ``capabilities`` field of struct +:ref:`v4l2_capability ` returned by the +:ref:`VIDIOC_QUERYCAP ` ioctl. As secondary device +functions they may also support the :ref:`video overlay ` +(``V4L2_CAP_VIDEO_OVERLAY``) and the :ref:`raw VBI capture ` +(``V4L2_CAP_VBI_CAPTURE``) interface. At least one of the read/write or +streaming I/O methods must be supported. Tuners and audio inputs are +optional. + + +Supplemental Functions +====================== + +Video capture devices shall support :ref:`audio input